version: "3.9" services: api: build: context: . dockerfile: Dockerfile.api ports: - "8000:8000" environment: PIT_DB_PATH: /data/pit.db PIT_RAW_DIR: /data/raw PIT_API_KEY: ${PIT_API_KEY:-} PIT_CONTACT_EMAIL: ${PIT_CONTACT_EMAIL:-} EPO_OPS_CONSUMER_KEY: ${EPO_OPS_CONSUMER_KEY:-} EPO_OPS_CONSUMER_SECRET: ${EPO_OPS_CONSUMER_SECRET:-} SEMANTICSCHOLAR_API_KEY: ${SEMANTICSCHOLAR_API_KEY:-} CLIMATIQ_API_KEY: ${CLIMATIQ_API_KEY:-} FOODDATA_CENTRAL_API_KEY: ${FOODDATA_CENTRAL_API_KEY:-} CLIMARKET_API_KEY: ${CLIMARKET_API_KEY:-${MARKET_API_KEY:-}} CLIMARKET_API_URL: ${CLIMARKET_API_URL:-https://cli-market-api.fly.dev} DATABASE_URL: ${DATABASE_URL:-postgresql://pit:pit@db:5432/pit} PIT_CORS_ORIGINS: ${PIT_CORS_ORIGINS:-http://localhost:3000} volumes: - pit_data:/data depends_on: db: condition: service_healthy healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/v1/health')"] interval: 30s timeout: 5s retries: 3 web: build: context: . dockerfile: Dockerfile args: NEXT_PUBLIC_PIT_API_URL: ${NEXT_PUBLIC_PIT_API_URL:-http://localhost:8000} ports: - "3000:8080" depends_on: - api db: image: postgres:16-alpine # Local-dev-only credentials — this container is never exposed outside # the compose network and production uses a managed Postgres instance # via DATABASE_URL, not this service. environment: POSTGRES_USER: pit POSTGRES_PASSWORD: pit POSTGRES_DB: pit volumes: - pit_pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U pit"] interval: 10s timeout: 5s retries: 5 volumes: pit_data: pit_pgdata: