Deploy the full Opentrace stack using Docker Compose. All four services (client, server, worker, Redis) run as containers.
services:
# Redis — Celery broker
redis:
image: redis:7-alpine
container_name: app_redis
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
# FastAPI Server
server:
build: { context: ./server, dockerfile: Dockerfile }
image: opentrace-server:latest
container_name: app_server
ports:
- "8000:8000"
env_file: ./server/.env
environment:
- REDIS_URL=redis://redis:6379/0
depends_on:
redis: { condition: service_healthy }
# Celery Worker (reuses server image)
celery_worker:
image: opentrace-server:latest
container_name: app_celery_worker
command: >
python -m celery -A src.services.celery:celery_app worker
--loglevel=info --pool=threads --concurrency=4
env_file: ./server/.env
environment:
- REDIS_URL=redis://redis:6379/0
depends_on:
redis: { condition: service_healthy }
# Next.js Client
client:
build:
context: ./client
dockerfile: Dockerfile
args:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY}
NEXT_PUBLIC_API_URL: http://localhost:8000
container_name: app_client
ports:
- "3000:3000"
depends_on:
server: { condition: service_healthy }# Build and start all services
docker compose --env-file .env.docker up --build -d
# View logs
docker compose logs -f
# Stop all services
docker compose downThe server image is built once and reused by the Celery worker — saving build time and ensuring both run the same code.
NEXT_PUBLIC_* environment variables are baked into the JavaScript bundle at build time. You must pass them as build args, not runtime environment variables.
| Service | Check |
|---|---|
| Redis | redis-cli ping |
| Server | curl http://localhost:8000/docs |
| Client | curl http://localhost:3000 |