docker-compose.yaml at the repository root is the reference deployment: ten containers, four volumes, one network. This page explains each part and how to change it.
Starting
make application-up rather than a bare docker compose up. The compose file’s own header says a bare up against a fresh checkout “will fail or come up misconfigured” — three services declare ${SECRET_KEY:?...} and abort without it.
The map
Services
Three services build from one image (
apps/api/Dockerfile) and differ only by command. See Workers and orchestrator.
minio-init exiting with code 0 is correct — it creates the bucket and stops. It is not a crash.Volumes
Network and the mongodb alias
One bridge network,app-network. The ferretdb service publishes the alias mongodb, so in-stack services connect to mongodb:27017 and nothing refers to FerretDB by name. See Data store.
Environment precedence
Each service loadsenv_file: .env, then applies its own environment: block — and environment: wins. Some values are pinned there deliberately, because the in-network address differs from the host one:
Editing these in
.env has no effect inside the stack. That is intended.
DEBUG is deliberately not interpolated into environment:. The compose file explains why: host shells often export DEBUG=release, which would override the boolean False from .env. It reaches containers through env_file only — so do not add DEBUG: "${DEBUG}".SECRET_KEY on api, arq-worker, and campaign-orchestrator.
Healthchecks and start order
api waits for FerretDB only to start, not to be ready. On a cold first boot it can attempt a query too early and log a connection error. restart: unless-stopped recovers it within seconds.Overriding ports
Every published port reads from.env:
Logs
Every service usesjson-file with max-size: 10m and max-file: 3 — about 30 MB per container, so logs cannot fill the disk.