# ============================================================================ # Structured Data Extraction — local Docker stack # # docker compose up --build # first run (or after Dockerfile changes) # docker compose up # subsequent runs # docker compose logs -f api # tail API logs # docker compose down # stop + remove containers # # The UI waits for the API healthcheck before it accepts traffic. Once both # are up, browse to http://localhost:5173 — the frontend's /api calls are # proxied by nginx into the api container over the compose network. # ============================================================================ services: api: build: context: . dockerfile: docker/api.Dockerfile image: sdx-api:latest container_name: sdx-api ports: - "8000:8000" env_file: # Only OPENAI_API_KEY is strictly required. Everything else is # optional and read via src/utils/config.py. - .env environment: # Fallbacks in case .env is missing keys — the app still starts. PYTHONPATH: /app LOG_LEVEL: ${LOG_LEVEL:-INFO} volumes: # Mount sample data read-only so the eval CLI can run in-container. # Nothing else from the host filesystem leaks in. - ./data/samples:/app/data/samples:ro healthcheck: test: ["CMD", "curl", "-fsS", "http://localhost:8000/health"] interval: 15s timeout: 3s start_period: 10s retries: 3 restart: unless-stopped networks: - sdx-net ui: build: context: . dockerfile: docker/ui.Dockerfile image: sdx-ui:latest container_name: sdx-ui ports: - "5173:5173" depends_on: api: # Only start once /health returns 200 — avoids the flash of proxy # errors when the frontend loads before FastAPI is ready. condition: service_healthy restart: unless-stopped networks: - sdx-net networks: sdx-net: driver: bridge