Docker Compose¶
Define and run multiple containers as one app with a YAML file. One
docker compose upstarts your model API, database, and UI together — with shared networks, volumes, and env vars.
Table of Contents¶
- Installation / Setup
- Core Syntax
- Common Operations
- Practical Examples
- Common Patterns
- Best Practices
- Common Mistakes
- Troubleshooting
- Related Cheat Sheets
- Official Documentation
Installation / Setup¶
docker compose version # bundled with Docker Desktop / modern engine
# classic standalone: pip install docker-compose (older v1 — avoid)
Create compose.yaml (or docker-compose.yml) in the project root. All commands run from that directory.
Core Syntax¶
The file¶
services: # each container = one service
api:
build: . # build from local Dockerfile
ports:
- "8000:8000"
environment:
- DB_URL=postgresql://db:5432/mydb
volumes:
- ./app:/app # bind mount for dev
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data # named volume persists data
volumes:
pgdata: # declare named volumes
networks: # (optional) custom networks
CLI¶
| Command | Does |
|---|---|
docker compose up |
build + start (foreground) |
docker compose up -d |
start detached |
docker compose up --build |
rebuild images first |
docker compose down |
stop + remove containers/network |
docker compose down -v |
also delete named volumes (data!) |
docker compose ps |
status |
docker compose logs -f api |
follow one service's logs |
docker compose exec api bash |
shell inside a service |
docker compose build |
build images only |
docker compose pull |
pull images only |
docker compose restart api |
restart one service |
Common Operations¶
Environment variables¶
services:
api:
environment:
MODEL_PATH: /models/best.pt # literal
- DATASET=big # or list form
env_file:
- .env # load from a file (gitignored!)
Secrets and per-developer config belong in .env (add to .gitignore); compose substitutes ${VAR}:
Healthchecks & dependencies¶
services:
api:
depends_on:
db:
condition: service_healthy # wait for db to be ready
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 10
Practical Examples¶
1. Data-science dev stack: Jupyter + Postgres¶
services:
jupyter:
image: jupyter/datascience-notebook:latest
ports: ["8888:8888"]
volumes:
- ./notebooks:/home/jovyan/work
environment:
JUPYTER_TOKEN: devtoken
db:
image: postgres:16
environment:
POSTGRES_USER: analyst
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: analysis
volumes:
- pgdata:/var/lib/postgresql/data
ports: ["5432:5432"]
volumes:
pgdata:
2. Model API + vector store (RAG service)¶
services:
api:
build: ./api
ports: ["8000:8000"]
environment:
EMBEDDING_MODEL: sentence-transformers/all-MiniLM-L6-v2
QDRANT_URL: http://qdrant:6333
depends_on:
qdrant:
condition: service_healthy
qdrant:
image: qdrant/qdrant:latest
volumes:
- qdrant_data:/qdrant/storage
healthcheck:
test: ["CMD", "bash", "-c", "exec 3<>/dev/tcp/localhost/6333"]
interval: 10s
retries: 5
3. Training job (one-shot)¶
services:
train:
build: .
command: python train.py --epochs 50
volumes:
- ./artifacts:/app/artifacts
environment:
- WANDB_MODE=offline
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
Common Patterns¶
# Reuse an image for multiple services with different commands
services:
worker:
image: myapp:latest
command: celery -A app worker
beat:
image: myapp:latest
command: celery -A app beat
# Profiles: optional services (dev tools) not started by default
services:
mlflow:
image: ghcr.io/mlflow/mlflow
profiles: ["tools"]
command: mlflow server --host 0.0.0.0
Best Practices¶
- Name the file
compose.yaml(modern default) and run commands from its directory. - Use
.envfor secrets/config, never hardcode; gitignore it. - Persist state in named volumes — container FS is disposable.
- Add healthchecks to databases and services you depend on.
depends_onwithcondition: service_healthy, not bare ordering.- Prefer
build: .in dev,image:(pulled from registry) in prod. - Pin image tags; avoid
latestfor anything important. - Split dev/prod with overrides:
docker compose -f compose.yaml -f compose.prod.yaml up -d. - Use profiles for optional tools instead of commenting services in/out.
Common Mistakes¶
| Mistake | Consequence | Fix |
|---|---|---|
Missing volumes: declaration for named volumes |
Compose error | Declare under top-level volumes: |
Secret in compose.yaml committed |
Leaked credentials | ${VAR} + .env gitignored |
depends_on only (no healthcheck) |
App starts before DB ready | condition: service_healthy |
down -v in production |
Wipes databases | Know that -v deletes volumes |
Editing .env but not restarting |
Stale env in running services | docker compose up -d again (recreates) |
| Forgetting ports for host access | Can't reach the service | Map host:container in ports |
Version field version: "3" |
Deprecated noise | Omit the version field (modern compose) |
| Building every run | Slow iteration | docker compose up --build only when Dockerfile changed |
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
service "api" is unhealthy |
Healthcheck failing | docker compose logs api; check test command |
port is already allocated |
Host port taken | Change mapping or stop the other app |
| Service restarts forever | Crash loop | docker compose logs <svc>; fix entrypoint |
Can't resolve db hostname |
Different network | All services share the default network — name it if custom |
Config from .env not applied |
.env not in project dir / cached |
Run compose from that dir; docker compose config to verify |
| Volume data "missing" | Wrong volume/path | docker volume ls; docker compose down kept volumes? |
| GPU not visible | No deploy resources / toolkit missing | Add deploy.resources; install nvidia-container-toolkit |
Related Cheat Sheets¶
- docker.md — single-container fundamentals, Dockerfiles, CLI
- github-actions.md — CI:
docker composefor test services - MLOps · Apps & UI — stacks you'll compose
- Linux — shell inside containers
- Home · Central Navigation Index
Official Documentation¶
- Docker Compose overview
- Compose file reference
- Compose CLI reference
- Environment variables in Compose
Last Updated¶
2026-09-06 — Initial version.