Docker Compose#
Single-node deployment for dev, laptop demos, and small PoCs. This is the mode the Quickstart uses.
What you get#
apicontainer — FastAPI backend + agent runtimedashboardcontainer — Next.js UIdbcontainer — Postgres 16 (or SQLite if you strip this)rediscontainer — cache (optional; used only for LLM response caching + rate-limiting)- Local volume mounts for
pipeline_runs/,ml_team/data/,~/.swarm/
Full docker-compose.yml#
version: '3.9'
services:
api:
image: ghcr.io/theaisingularity/swarm-api:0.11.0
restart: unless-stopped
ports:
- "8000:8000"
env_file:
- .env
environment:
SWARM_DB_URL: postgresql://swarm:swarm@db:5432/swarm
SWARM_API_HOST: 0.0.0.0
SWARM_API_PORT: 8000
volumes:
- ./ml_team/data:/app/ml_team/data
- ./pipeline_runs:/app/pipeline_runs
- swarm-state:/root/.swarm
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/healthz"]
interval: 30s
timeout: 5s
retries: 3
dashboard:
image: ghcr.io/theaisingularity/swarm-dashboard:0.11.0
restart: unless-stopped
ports:
- "3000:3000"
environment:
NEXT_PUBLIC_API_URL: http://localhost:8000
depends_on:
- api
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: swarm
POSTGRES_PASSWORD: swarm
POSTGRES_DB: swarm
volumes:
- swarm-db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U swarm"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
restart: unless-stopped
ports:
- "6379:6379"
volumes:
swarm-db:
swarm-state:
File at deploy/compose/docker-compose.yml.
.env template#
# Authentication
SWARM_JWT_SECRET=<generate-a-long-random-string>
# LLM providers
ANTHROPIC_API_KEY=sk-ant-...
# or
OPENAI_API_KEY=sk-proj-...
# Logging
SWARM_LOG_LEVEL=INFO
First boot#
cp .env.example .env # edit with your keys
docker compose up -d
docker compose logs -f api # watch startup; grep for "SEEDED ADMIN" to get password
Common operations#
Restart one service#
Upgrade#
docker compose pull # pull latest images
docker compose up -d # recreate with new images
# verify
curl http://localhost:8000/healthz
Backup#
Restore#
Reset everything#
Resource sizing#
For dev/demo (single user, 1-2 pipelines at a time):
- Docker Desktop → Settings → Resources → 6 CPUs, 12 GB RAM, 40 GB disk
- Linux: no hard limits needed; fits on 8-core / 16-GB laptop
For a small team (3-5 users, 10 pipelines/day):
- Move Postgres to managed (Neon / Supabase free tier) — see
SWARM_DB_URL - Increase
SWARM_API_WORKERSto 4 - Move object storage to S3 / GCS (
SWARM_STORAGE_BACKEND=s3)
At that point you're on the path to Kubernetes. Proceed to Kubernetes + Helm.
When NOT to use Docker Compose#
- > 10 concurrent pipelines — single-replica API bottlenecks
- Enterprise procurement — customers want Kubernetes artefacts for security review
- Multi-tenant SaaS — Compose has no namespace isolation
- HA / 99.95% SLA — single container = single point of failure
Using Compose for a proper PoC#
If a prospect wants a self-hosted PoC but isn't ready for K8s, Compose + a reverse proxy + managed Postgres is fine:
# Add nginx / Caddy in front of api + dashboard
# for TLS + custom domain:
services:
proxy:
image: caddy:2-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy-data:/data
# Caddyfile
swarm.customer.com {
reverse_proxy dashboard:3000
}
api.swarm.customer.com {
reverse_proxy api:8000
}
Auto-TLS via Let's Encrypt. Still single-node, but customer-accessible.
Troubleshooting#
Port 8000 already in use
lsof -i :8000 to find the other process. Remap: ports: - "18000:8000" and update NEXT_PUBLIC_API_URL.
Postgres hangs at startup
Delete the volume: docker volume rm swarm_swarm-db. Data loss — make sure you've backed up.
Dashboard can't reach API
Different hosts from container's perspective. In docker-compose, NEXT_PUBLIC_API_URL should use the service name (http://api:8000) for server-to-server, http://localhost:8000 for browser. Default config handles this via reverse proxy logic in the dashboard.
Next#
- Kubernetes + Helm — production path
- Upgrade & versioning — LTS policy
- Operations: Backup & restore