Skip to content

Commit 1f6a704

Browse files
authored
Merge pull request #483 from traceroot-ai/xinwei_prod_dockerfile_support_v1
[AgentOps] Standalone prod Docker + GitHub App integration fixes
2 parents a2c1ea1 + 4f575b3 commit 1f6a704

File tree

23 files changed

+904
-33
lines changed

23 files changed

+904
-33
lines changed

.dockerignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# .dockerignore
2+
.git
3+
.github
4+
.vscode
5+
.claude
6+
node_modules
7+
__pycache__
8+
*.pyc
9+
.next
10+
.env
11+
.env.*
12+
*.md
13+
test_*.py

Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,23 @@ dev-reset:
2121
rm -rf frontend/node_modules frontend/ui/node_modules frontend/worker/node_modules frontend/packages/core/node_modules
2222
rm -rf .venv
2323
uv run python tmux_tools/launcher.py
24+
25+
# --- Production (Docker) ---------------------------------------------------
26+
27+
PROD_COMPOSE := docker compose -f docker-compose.prod.yml
28+
29+
.PHONY: prod prod-down prod-reset
30+
31+
## Start all services in Docker with tmux log viewer (builds on first run).
32+
prod:
33+
uv run python tmux_tools/launcher.py --prod
34+
35+
## Stop all production containers.
36+
prod-down:
37+
$(PROD_COMPOSE) down
38+
39+
## Nuclear reset: stop containers, remove volumes and built images.
40+
prod-reset:
41+
@echo "Resetting production environment..."
42+
tmux -L development kill-session -t traceroot-prod 2>/dev/null || true
43+
$(PROD_COMPOSE) down -v --rmi local

backend/worker/celery_app.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,12 @@ def on_worker_ready(**kwargs):
8383
logger.info(f"goose: {line}")
8484

8585
if result.returncode != 0:
86-
raise RuntimeError(f"goose migration failed: {result.stderr}")
86+
logger.warning(f"ClickHouse migration skipped: {result.stderr.strip()}")
87+
return
8788

8889
logger.info("ClickHouse migrations completed successfully")
8990

9091
except FileNotFoundError:
91-
logger.warning("goose not found. Install with: brew install goose")
92-
raise
92+
logger.warning("goose not found, skipping ClickHouse migrations.")
9393
except Exception as e:
9494
logger.error(f"ClickHouse migration failed: {e}")
95-
raise

docker-compose.prod.yml

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
# docker-compose.prod.yml
2+
# Standalone production compose. Runs everything: infra + app services.
3+
# Usage: docker compose -f docker-compose.prod.yml up --build
4+
#
5+
# All configurable values use ${VAR:-default} so they can be overridden via
6+
# .env (local) or environment injection (AWS ECS, K8s, etc.).
7+
8+
services:
9+
# ---------------------------------------------------------------------------
10+
# Infrastructure
11+
# ---------------------------------------------------------------------------
12+
postgres:
13+
image: docker.io/postgres:${POSTGRES_VERSION:-17}
14+
restart: always
15+
environment:
16+
POSTGRES_USER: ${POSTGRES_USER:-postgres}
17+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
18+
POSTGRES_DB: ${POSTGRES_DB:-postgres}
19+
TZ: UTC
20+
PGTZ: UTC
21+
ports:
22+
- 127.0.0.1:5432:5432
23+
volumes:
24+
- postgres_data:/var/lib/postgresql/data
25+
healthcheck:
26+
test: ["CMD-SHELL", "pg_isready -U postgres"]
27+
interval: 3s
28+
timeout: 3s
29+
retries: 10
30+
31+
clickhouse:
32+
image: docker.io/clickhouse/clickhouse-server:${CLICKHOUSE_VERSION:-24.3}
33+
restart: always
34+
environment:
35+
CLICKHOUSE_DB: ${CLICKHOUSE_DB:-default}
36+
CLICKHOUSE_USER: ${CLICKHOUSE_USER:-clickhouse}
37+
CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD:-clickhouse}
38+
ports:
39+
- 127.0.0.1:8123:8123
40+
- 127.0.0.1:9000:9000
41+
volumes:
42+
- clickhouse_data:/var/lib/clickhouse
43+
- clickhouse_logs:/var/log/clickhouse-server
44+
healthcheck:
45+
test: wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1
46+
interval: 5s
47+
timeout: 5s
48+
retries: 10
49+
start_period: 1s
50+
51+
minio:
52+
image: docker.io/minio/minio:latest
53+
restart: always
54+
command: server /data --console-address ":9001"
55+
environment:
56+
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minio}
57+
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minio-password}
58+
ports:
59+
- 9090:9000
60+
- 127.0.0.1:9091:9001
61+
volumes:
62+
- minio_data:/data
63+
healthcheck:
64+
test: ["CMD", "mc", "ready", "local"]
65+
interval: 5s
66+
timeout: 5s
67+
retries: 5
68+
start_period: 1s
69+
70+
minio-init:
71+
image: docker.io/minio/mc:latest
72+
depends_on:
73+
minio:
74+
condition: service_healthy
75+
entrypoint: >
76+
/bin/sh -c "
77+
mc alias set myminio http://minio:9000 $${MINIO_ROOT_USER:-minio} $${MINIO_ROOT_PASSWORD:-minio-password};
78+
mc mb myminio/traceroot --ignore-existing;
79+
exit 0;
80+
"
81+
82+
redis:
83+
image: docker.io/redis:7-alpine
84+
restart: always
85+
command: redis-server --appendonly yes
86+
ports:
87+
- 127.0.0.1:6379:6379
88+
volumes:
89+
- redis_data:/data
90+
healthcheck:
91+
test: ["CMD", "redis-cli", "ping"]
92+
interval: 3s
93+
timeout: 3s
94+
retries: 10
95+
96+
# ---------------------------------------------------------------------------
97+
# Migrations (run once before app services start)
98+
# ---------------------------------------------------------------------------
99+
migrate:
100+
build:
101+
context: .
102+
dockerfile: docker/Dockerfile.web
103+
target: migrate
104+
environment:
105+
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres
106+
depends_on:
107+
postgres:
108+
condition: service_healthy
109+
restart: "no"
110+
111+
migrate-clickhouse:
112+
build:
113+
context: .
114+
dockerfile: docker/Dockerfile.migrate-clickhouse
115+
command: ["clickhouse://clickhouse:clickhouse@clickhouse:9000/default", "up"]
116+
depends_on:
117+
clickhouse:
118+
condition: service_healthy
119+
restart: "no"
120+
121+
# ---------------------------------------------------------------------------
122+
# Application services
123+
# ---------------------------------------------------------------------------
124+
web:
125+
build:
126+
context: .
127+
dockerfile: docker/Dockerfile.web
128+
args:
129+
NEXTAUTH_SECRET: ${NEXTAUTH_SECRET:-local-dev-secret-change-in-production}
130+
ports:
131+
- "3000:3000"
132+
environment:
133+
# --- Internal Docker networking (fixed) ---
134+
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres
135+
AGENT_SERVICE_URL: http://agent:8100
136+
TRACEROOT_UI_URL: http://web:3000
137+
# --- Auth ---
138+
NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000}
139+
NEXTAUTH_SECRET: ${NEXTAUTH_SECRET:-local-dev-secret-change-in-production}
140+
AUTH_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID:-}
141+
AUTH_GOOGLE_CLIENT_SECRET: ${AUTH_GOOGLE_CLIENT_SECRET:-}
142+
# --- API ---
143+
# NOTE: NEXT_PUBLIC_* vars are baked at build time in Next.js.
144+
# For production, rebuild the image with the correct value or use
145+
# runtime env rewriting in next.config.js.
146+
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8000/api/v1}
147+
INTERNAL_API_SECRET: ${INTERNAL_API_SECRET:-internal-secret}
148+
# --- AI keys ---
149+
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
150+
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
151+
# --- Encryption ---
152+
ENCRYPTION_KEY: ${ENCRYPTION_KEY:-}
153+
# --- Billing ---
154+
ENABLE_BILLING: ${ENABLE_BILLING:-true}
155+
STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY:-}
156+
STRIPE_WEBHOOK_SIGNING_SECRET: ${STRIPE_WEBHOOK_SIGNING_SECRET:-}
157+
STRIPE_PRICE_ID_STARTER: ${STRIPE_PRICE_ID_STARTER:-}
158+
STRIPE_PRICE_ID_PRO: ${STRIPE_PRICE_ID_PRO:-}
159+
STRIPE_PRICE_ID_STARTUPS: ${STRIPE_PRICE_ID_STARTUPS:-}
160+
# --- GitHub App ---
161+
GITHUB_APP_ID: ${GITHUB_APP_ID:-}
162+
GITHUB_APP_NAME: ${GITHUB_APP_NAME:-}
163+
GITHUB_APP_PRIVATE_KEY: ${GITHUB_APP_PRIVATE_KEY:-}
164+
GITHUB_APP_CLIENT_ID: ${GITHUB_APP_CLIENT_ID:-}
165+
GITHUB_APP_CLIENT_SECRET: ${GITHUB_APP_CLIENT_SECRET:-}
166+
GITHUB_OAUTH_REDIRECT_URI: ${GITHUB_OAUTH_REDIRECT_URI:-http://localhost:3000/api/github/callback}
167+
# --- Email ---
168+
TRACEROOT_SMTP_URL: ${TRACEROOT_SMTP_URL:-}
169+
TRACEROOT_SMTP_MAIL_FROM: ${TRACEROOT_SMTP_MAIL_FROM:-}
170+
# --- Enterprise ---
171+
TRACEROOT_EE_LICENSE_KEY: ${TRACEROOT_EE_LICENSE_KEY:-}
172+
depends_on:
173+
postgres:
174+
condition: service_healthy
175+
migrate:
176+
condition: service_completed_successfully
177+
178+
rest:
179+
build:
180+
context: .
181+
dockerfile: docker/Dockerfile.rest
182+
ports:
183+
- "8000:8000"
184+
environment:
185+
# --- Internal Docker networking (fixed) ---
186+
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres
187+
CLICKHOUSE_HOST: clickhouse
188+
CLICKHOUSE_PORT: "8123"
189+
CLICKHOUSE_NATIVE_PORT: "9000"
190+
CLICKHOUSE_USER: ${CLICKHOUSE_USER:-clickhouse}
191+
CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD:-clickhouse}
192+
CLICKHOUSE_DATABASE: ${CLICKHOUSE_DATABASE:-default}
193+
REDIS_URL: redis://redis:6379/0
194+
REDIS_RESULT_URL: redis://redis:6379/1
195+
S3_ENDPOINT_URL: http://minio:9000
196+
S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-minio}
197+
S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY:-minio-password}
198+
S3_BUCKET_NAME: ${S3_BUCKET_NAME:-traceroot}
199+
S3_REGION: ${S3_REGION:-us-east-1}
200+
TRACEROOT_UI_URL: http://web:3000
201+
# --- Secrets ---
202+
INTERNAL_API_SECRET: ${INTERNAL_API_SECRET:-internal-secret}
203+
CORS_ORIGINS: ${CORS_ORIGINS:-["http://localhost:3000"]}
204+
depends_on:
205+
migrate:
206+
condition: service_completed_successfully
207+
migrate-clickhouse:
208+
condition: service_completed_successfully
209+
redis:
210+
condition: service_healthy
211+
212+
worker:
213+
build:
214+
context: .
215+
dockerfile: docker/Dockerfile.worker
216+
environment:
217+
# --- Internal Docker networking (fixed) ---
218+
CLICKHOUSE_HOST: clickhouse
219+
CLICKHOUSE_PORT: "8123"
220+
CLICKHOUSE_NATIVE_PORT: "9000"
221+
CLICKHOUSE_USER: ${CLICKHOUSE_USER:-clickhouse}
222+
CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD:-clickhouse}
223+
CLICKHOUSE_DATABASE: ${CLICKHOUSE_DATABASE:-default}
224+
REDIS_URL: redis://redis:6379/0
225+
REDIS_RESULT_URL: redis://redis:6379/1
226+
S3_ENDPOINT_URL: http://minio:9000
227+
S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-minio}
228+
S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY:-minio-password}
229+
S3_BUCKET_NAME: ${S3_BUCKET_NAME:-traceroot}
230+
S3_REGION: ${S3_REGION:-us-east-1}
231+
# --- Worker config ---
232+
POLL_INTERVAL_SECONDS: ${POLL_INTERVAL_SECONDS:-5}
233+
BATCH_SIZE: ${BATCH_SIZE:-100}
234+
depends_on:
235+
migrate-clickhouse:
236+
condition: service_completed_successfully
237+
redis:
238+
condition: service_healthy
239+
240+
billing:
241+
build:
242+
context: .
243+
dockerfile: docker/Dockerfile.billing
244+
environment:
245+
# --- Internal Docker networking (fixed) ---
246+
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres
247+
CLICKHOUSE_HOST: clickhouse
248+
CLICKHOUSE_PORT: "8123"
249+
CLICKHOUSE_USER: ${CLICKHOUSE_USER:-clickhouse}
250+
CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD:-clickhouse}
251+
CLICKHOUSE_DATABASE: ${CLICKHOUSE_DATABASE:-default}
252+
REDIS_URL: redis://redis:6379/0
253+
BACKEND_INTERNAL_URL: http://rest:8000
254+
# --- Secrets ---
255+
INTERNAL_API_SECRET: ${INTERNAL_API_SECRET:-internal-secret}
256+
# --- Billing ---
257+
ENABLE_BILLING: ${ENABLE_BILLING:-true}
258+
STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY:-}
259+
STRIPE_WEBHOOK_SIGNING_SECRET: ${STRIPE_WEBHOOK_SIGNING_SECRET:-}
260+
STRIPE_PRICE_ID_STARTER: ${STRIPE_PRICE_ID_STARTER:-}
261+
STRIPE_PRICE_ID_PRO: ${STRIPE_PRICE_ID_PRO:-}
262+
STRIPE_PRICE_ID_STARTUPS: ${STRIPE_PRICE_ID_STARTUPS:-}
263+
# --- Worker config ---
264+
USAGE_METERING_CRON: ${USAGE_METERING_CRON:-"5 * * * *"}
265+
depends_on:
266+
migrate:
267+
condition: service_completed_successfully
268+
migrate-clickhouse:
269+
condition: service_completed_successfully
270+
271+
agent:
272+
build:
273+
context: .
274+
dockerfile: docker/Dockerfile.agent
275+
ports:
276+
- "8100:8100"
277+
volumes:
278+
- /var/run/docker.sock:/var/run/docker.sock
279+
environment:
280+
# --- Internal Docker networking (fixed) ---
281+
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres
282+
AGENT_SERVICE_URL: http://agent:8100
283+
BACKEND_INTERNAL_URL: http://rest:8000
284+
TRACEROOT_UI_URL: http://web:3000
285+
# --- Secrets ---
286+
INTERNAL_API_SECRET: ${INTERNAL_API_SECRET:-internal-secret}
287+
ENCRYPTION_KEY: ${ENCRYPTION_KEY:-}
288+
# --- Sandbox ---
289+
SANDBOX_PROVIDER: ${SANDBOX_PROVIDER:-docker}
290+
DAYTONA_API_KEY: ${DAYTONA_API_KEY:-}
291+
# --- AI keys ---
292+
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
293+
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
294+
depends_on:
295+
migrate:
296+
condition: service_completed_successfully
297+
298+
volumes:
299+
postgres_data:
300+
driver: local
301+
clickhouse_data:
302+
driver: local
303+
clickhouse_logs:
304+
driver: local
305+
minio_data:
306+
driver: local
307+
redis_data:
308+
driver: local

0 commit comments

Comments
 (0)