services: # Local dev only — production points DATABASE_URL at RDS instead. Start with # `docker compose --profile local up ...` to include this service. db: image: postgres:16 profiles: ["local"] environment: POSTGRES_DB: brainwidebench POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - "5434:5432" volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 5s timeout: 3s retries: 5 redis: image: redis:7-alpine # requirepass is empty (auth disabled) when REDIS_PASSWORD is unset, which keeps this # working for local dev without every developer needing one. Production sets it via # .env, and REDIS_URL must carry the same password. `expose` rather than `ports`: only # `web`/`worker` need it, over the compose network — it has no business reachable from # the host, let alone the internet. command: ["redis-server", "--requirepass", "${REDIS_PASSWORD:-}"] expose: - "6379" web: build: context: . dockerfile: Dockerfile command: uv run uvicorn app.main:app --host 0.0.0.0 --port 8080 expose: - "8080" env_file: .env depends_on: db: condition: service_healthy required: false redis: condition: service_started nginx: image: nginx:1.27-alpine ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - web restart: unless-stopped worker: build: context: . dockerfile: Dockerfile command: uv run celery -A app.worker worker --loglevel=info env_file: .env environment: TMPDIR: /scratch volumes: - ${BWB_SCRATCH_DIR:-./.data/scratch}:/scratch - ${BWB_GT_DIR:-./.data/ground-truth}:/ground-truth depends_on: db: condition: service_healthy required: false redis: condition: service_started volumes: postgres_data: