# earth-now.co # Author: Simon-Pierre Boucher # Contact: contact@spboucher.ai # File: infra/docker-compose.prod.yml # Purpose: Production stack on node m3u96b — web, api, ingest, TimescaleDB, Redis, nginx proxy (ngrok fronts port 8080) # # Secrets come from a `.env` file next to this compose file (or the shell env). # NEVER commit tokens or passwords — POSTGRES_PASSWORD and NGROK_AUTHTOKEN live in the # environment / secret manager only. services: web: build: context: .. dockerfile: infra/docker/web.Dockerfile restart: unless-stopped environment: NODE_ENV: production PORT: "3000" API_ORIGIN: http://api:4000 expose: - "3000" depends_on: - api api: build: context: .. dockerfile: infra/docker/api.Dockerfile restart: unless-stopped environment: NODE_ENV: production PORT: "4000" DATABASE_URL: postgres://earthnow:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in .env}@db:5432/earthnow REDIS_URL: redis://redis:6379 expose: - "4000" depends_on: - db - redis ingest: build: context: .. dockerfile: infra/docker/ingest.Dockerfile restart: unless-stopped environment: NODE_ENV: production DATABASE_URL: postgres://earthnow:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in .env}@db:5432/earthnow REDIS_URL: redis://redis:6379 RAW_ARCHIVE_DIR: /data/raw volumes: # We keep ALL raw ingested data for re-fitting (S3 later). - raw_archive:/data/raw depends_on: - db - redis db: image: timescale/timescaledb:latest-pg16 restart: unless-stopped environment: POSTGRES_USER: earthnow POSTGRES_DB: earthnow POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in .env} volumes: - db_data:/var/lib/postgresql/data # Bootstrap schema on first start; later migrations run via `pnpm db:migrate`. - ./migrations:/docker-entrypoint-initdb.d:ro expose: - "5432" redis: image: redis:7-alpine restart: unless-stopped expose: - "6379" proxy: image: nginx:alpine restart: unless-stopped ports: # ngrok (reserved domain www.earth-now.co) fronts this port on the host. - "8080:80" volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - web - api volumes: db_data: raw_archive: