version: "3.9" name: fr24-ingest x-common-env: &common-env TZ: ${TZ:-UTC} APP_ENV: ${APP_ENV:-dev} POSTGRES_HOST: ${POSTGRES_HOST:-postgres} POSTGRES_PORT: ${POSTGRES_PORT:-5432} POSTGRES_DB: ${POSTGRES_DB:-fr24} POSTGRES_USER: ${POSTGRES_USER:-fr24} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change-me} RAW_RETENTION_DAYS: ${RAW_RETENTION_DAYS:-3} PARTITION_RETENTION_DAYS: ${PARTITION_RETENTION_DAYS:-3} OVERLAP_MINUTES: ${OVERLAP_MINUTES:-10} CAPTURE_SOURCE: ${CAPTURE_SOURCE:-rtl-sdr} RTLSDR_DEVICE_INDEX: ${RTLSDR_DEVICE_INDEX:-0} RTLSDR_SAMPLE_RATE: ${RTLSDR_SAMPLE_RATE:-2000000} RTLSDR_CENTER_FREQUENCY: ${RTLSDR_CENTER_FREQUENCY:-1090000000} RTLSDR_GAIN: ${RTLSDR_GAIN:-auto} services: postgres: image: postgis/postgis:16-3.4 container_name: fr24-postgres environment: POSTGRES_DB: ${POSTGRES_DB:-fr24} POSTGRES_USER: ${POSTGRES_USER:-fr24} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change-me} TZ: ${TZ:-UTC} ports: - "${POSTGRES_PUBLISHED_PORT:-5432}:5432" volumes: - ../db/postgres:/var/lib/postgresql/data - ../db/init:/docker-entrypoint-initdb.d:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-fr24} -d ${POSTGRES_DB:-fr24}"] interval: 10s timeout: 5s retries: 5 start_period: 20s restart: unless-stopped networks: - fr24-net capture: build: context: ../ingest/capture dockerfile: Dockerfile image: fr24-capture container_name: fr24-capture environment: <<: *common-env SERVICE_ROLE: capture devices: - "/dev/bus/usb:/dev/bus/usb" volumes: - ../logs/capture:/var/log/fr24 - ../backup:/backup depends_on: postgres: condition: service_healthy healthcheck: test: ["CMD-SHELL", "test -f /tmp/capture-ready && python -c 'import psycopg2' 2>/dev/null || exit 1"] interval: 30s timeout: 5s retries: 3 start_period: 10s restart: unless-stopped networks: - fr24-net preprocess: build: context: ../ingest/preprocess dockerfile: Dockerfile image: fr24-preprocess container_name: fr24-preprocess environment: <<: *common-env SERVICE_ROLE: preprocess volumes: - ../logs/preprocess:/var/log/fr24 - ../backup:/backup depends_on: postgres: condition: service_healthy capture: condition: service_started healthcheck: test: ["CMD-SHELL", "test -f /tmp/preprocess-ready && python -c 'import psycopg2' 2>/dev/null || exit 1"] interval: 30s timeout: 5s retries: 3 start_period: 10s restart: unless-stopped networks: - fr24-net api: build: context: ../frontend dockerfile: Dockerfile image: fr24-api container_name: fr24-api environment: <<: *common-env SERVICE_ROLE: api API_PORT: ${API_PORT:-8080} ports: - "${API_PUBLISHED_PORT:-8080}:8080" volumes: - ../logs/api:/var/log/fr24 depends_on: postgres: condition: service_healthy preprocess: condition: service_started healthcheck: test: ["CMD-SHELL", "wget -qO- http://localhost:8080/health || exit 1"] interval: 30s timeout: 5s retries: 3 start_period: 10s restart: unless-stopped networks: - fr24-net monitoring: image: alpine:3.20 container_name: fr24-monitoring command: ["sh", "-c", "echo 'monitoring placeholder: disk, db, capture status, alerts'; tail -f /dev/null"] environment: <<: *common-env SERVICE_ROLE: monitoring MONITORING_INTERVAL_SECONDS: ${MONITORING_INTERVAL_SECONDS:-30} ports: - "${MONITORING_PUBLISHED_PORT:-9090}:9090" volumes: - ../logs/monitoring:/var/log/fr24 - ../backup:/backup - /var/run/docker.sock:/var/run/docker.sock:ro depends_on: postgres: condition: service_healthy capture: condition: service_started preprocess: condition: service_started api: condition: service_started healthcheck: test: ["CMD-SHELL", "test -f /tmp/monitoring-ready || exit 1"] interval: 30s timeout: 5s retries: 3 start_period: 10s restart: unless-stopped networks: - fr24-net networks: fr24-net: name: fr24-net driver: bridge