-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
114 lines (112 loc) · 4.66 KB
/
Copy pathdocker-compose.yml
File metadata and controls
114 lines (112 loc) · 4.66 KB
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# ---- CFDQandA Docker Compose ----
#
# Orchestrates two services:
# - api: FastAPI server (lightweight, ~200 MB image, ~200 MB RAM)
# - worker: Foam-Agent Worker (heavy, ~5-8 GB image, ~4.5 GB RAM per replica)
#
# Prerequisites:
# 1. Build images first:
# docker build -f Dockerfile.api -t cfdqanda-api .
# docker build -f Dockerfile.worker -t cfdqanda-worker .
# 2. Copy .env.example -> .env and fill in credentials
# 3. Clone Foam-Agent repo to the path specified in FOAM_AGENT_HOST_PATH
#
# Usage:
# docker compose up -d # Start all services
# docker compose up -d --scale worker=2 # Start with 2 Workers
# docker compose logs -f worker # Follow Worker logs
# docker compose ps # Check service status
# docker compose down # Stop all services
#
# Network: cloudflared (running on host) forwards api.foam-agent.com (and api.cfdqanda.com) -> localhost:8000
services:
# --- API Server ---
# Lightweight FastAPI server handling HTTP requests.
# cloudflared on the host forwards external HTTPS traffic to port 8000.
api:
image: cfdqanda-api:latest
container_name: cfdqanda-api
ports:
- "8000:8000"
env_file: .env
volumes:
# Bind mount api_server.py so git pull takes effect without rebuild
- ./api_server.py:/app/api_server.py:ro
environment:
# Worker health URL for the admin status endpoint.
# In Docker Compose, API reaches Worker by service name.
- WORKER_HEALTH_URL=http://worker:8001/health
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/')"]
interval: 30s
timeout: 5s
start_period: 10s
retries: 3
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
# --- Worker ---
# Polls Supabase for queued jobs, runs Foam-Agent subprocess (OpenFOAM + LLM).
# Each replica is an independent process that claims jobs atomically via
# PostgreSQL FOR UPDATE SKIP LOCKED — safe to scale to multiple replicas.
#
# Memory: ~4.5 GB per replica (Qwen3-Embedding-0.6B model = 3.4 GB).
# On 16 GB VM: max 2 replicas safely, 3 at the limit.
worker:
image: cfdqanda-worker:latest
env_file: .env
environment:
# Override FOAM_AGENT_DIR to match the bind mount path inside the container.
# The .env file may have a host-specific path (e.g. /home/yzeng/Codes/...),
# but inside the container it's always at this fixed path.
- FOAM_AGENT_DIR=/home/openfoam/Foam-Agent
# Override MIDDLEWARE_DIR to match the bind mount path inside the container.
- MIDDLEWARE_DIR=/app/middleware
volumes:
# Bind mount Worker scripts from host into the container.
# This overrides the baked-in copies so git pull takes effect immediately
# without needing to rebuild the Docker image.
- ./worker.py:/app/worker/worker.py:ro
- ./mcp_client.py:/app/worker/mcp_client.py:ro
- ./allrun_validator.py:/app/worker/allrun_validator.py:ro
- ./token_extractor.py:/app/worker/token_extractor.py:ro
# Bind mount Foam-Agent repo from host into the container.
# This overrides the baked-in copy, allowing git pull without rebuilding.
# Set FOAM_AGENT_HOST_PATH in .env to the absolute host path.
- ${FOAM_AGENT_HOST_PATH:-./Foam-Agent}:/home/openfoam/Foam-Agent
# Mount Codex OAuth token for openai-codex provider.
# On host: ~/.codex/auth.json (created by `codex login`)
- ~/.codex:/home/openfoam/.codex:ro
# Mount checkpoint middleware (optional, enables pre-run mechanism).
# Set MIDDLEWARE_HOST_PATH in .env to the absolute host path.
- ${MIDDLEWARE_HOST_PATH:-./cfdqanda-middleware}:/app/middleware
# Persist HuggingFace model cache (Qwen embedding model, ~1.2 GB) on the
# host so it survives container recreate/rebuild instead of re-downloading
# on every run. One shared copy, like bare-metal ~/.cache/huggingface.
- ${HF_CACHE_HOST_PATH:-/mnt/bigdata/hf-cache}:/home/openfoam/.cache/huggingface
restart: unless-stopped
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8001/health')"]
interval: 30s
timeout: 5s
start_period: 30s
retries: 3
deploy:
replicas: 1 # Scale: docker compose up -d --scale worker=2
resources:
limits:
memory: 5G
reservations:
memory: 3G
logging:
driver: json-file
options:
max-size: "50m"
max-file: "5"