# OSINT Dashboard — container stack (all env-driven, 12-factor). # Single combined TimescaleDB+PostGIS image is pinned to pg13 because that is # the only arm64 build Timescale publishes with PostGIS bundled. The app uses # only standard SQL types, so pg13 is fully sufficient. # # Bring up: docker compose up -d # With NATS: docker compose --profile ingest up -d # Env: copy .env.example to .env and adjust. services: db: build: context: . dockerfile: Dockerfile.pg platforms: ["linux/arm64"] image: localhost/osint-dashboard-pg:latest container_name: osint-db restart: unless-stopped environment: POSTGRES_USER: ${DB_USER:-osint} POSTGRES_PASSWORD: ${DB_PASSWORD:-osint} POSTGRES_DB: ${DB_NAME:-osint_data} # Ensure TimescaleDB is preloaded (conf.d drop-in may be ignored by the # official image's runtime-generated postgresql.conf, so pass it explicitly). command: ["-c", "shared_preload_libraries=timescaledb"] ports: - "127.0.0.1:5432:5432" volumes: - osint-pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-osint} -d ${DB_NAME:-osint_data}"] interval: 10s timeout: 5s retries: 10 nats: image: nats:2.10 platform: linux/arm64 container_name: osint-nats restart: unless-stopped profiles: ["ingest"] ports: - "127.0.0.1:4222:4222" - "127.0.0.1:8222:8222" command: ["-js"] ingester: build: context: . dockerfile: Dockerfile platforms: ["linux/arm64"] image: localhost/osint-dashboard:latest container_name: osint-ingester restart: unless-stopped profiles: ["ingest"] depends_on: nats: condition: service_started db: condition: service_healthy environment: DB_USER: ${DB_USER:-osint} DB_PASSWORD: ${DB_PASSWORD:-osint} DB_HOST: db DB_PORT: ${DB_PORT:-5432} DB_NAME: ${DB_NAME:-osint_data} NATS_URL: ${NATS_URL:-nats://nats:4222} RSS_URL: ${RSS_URL:-} GDELT_QUERY: ${GDELT_QUERY:-} INGEST_INTERVAL: ${INGEST_INTERVAL:-300} INGEST_EARTHQUAKES: ${INGEST_EARTHQUAKES:-1} command: ["python", "app/run_ingester.py"] entrypoint: ["python", "app/run_ingester.py"] app: build: context: . dockerfile: Dockerfile platforms: ["linux/arm64"] image: localhost/osint-dashboard:latest container_name: osint-dashboard restart: unless-stopped depends_on: db: condition: service_healthy environment: DB_USER: ${DB_USER:-osint} DB_PASSWORD: ${DB_PASSWORD:-osint} DB_HOST: db DB_PORT: ${DB_PORT:-5432} DB_NAME: ${DB_NAME:-osint_data} NATS_URL: ${NATS_URL:-nats://nats:4222} MINIO_ENDPOINT: ${MINIO_ENDPOINT:-minio:9000} MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-} MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-} MINIO_SECURE: ${MINIO_SECURE:-false} ports: - "127.0.0.1:8000:8000" healthcheck: test: ["CMD-SHELL", "python -c \"import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8000/api/health').status==200 else 1)\""] interval: 30s timeout: 5s retries: 5 volumes: osint-pgdata: