File size: 2,016 Bytes
6267e20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# ============================================================================
# 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