Docker Compose
Compose defines your whole application stack in one YAML file: services, networks, volumes and dependencies. It turns 'run these 5 docker commands' into docker compose up.
What is this?
Docker Compose is a tool for defining and running multi-container applications. A docker-compose.yml declares every service, its image/build, ports, env, volumes and networks. Compose creates the networks and volumes automatically and wires everything together.
Why do you need it?
- One file replaces a fragile chain of docker run commands.
- Config is version-controlled and reviewable like code.
- Automatic network creation gives every service DNS by its service name.
- Repeatable: the same file produces the same stack on any machine.
Mental model
An assembly manual
docker-compose.yml
The manual lists every part (services) and how they fit (networks/volumes). Anyone who follows it builds the same product — every environment gets the same stack.
How it works
- Compose reads the YAML and computes the full resource graph (services, networks, volumes).
- docker compose up creates resources in dependency order (depends_on).
- Services on the same project share a default network and resolve each other by service name.
- Volumes declared at the top level are created once and reused across service restarts.
- docker compose down removes the project's containers and, with -v, its volumes.
A Compose stack's resource graph.
Key commands
docker compose up -dStart the stack detached.
docker compose down -vStop and remove containers AND volumes.
docker compose psShow service status.
docker compose logs -f apiStream logs for one service.
docker compose up --build -dRebuild images then start.
Examples
A three-service stack
services: web: image: nginx ports: ["8080:80"] depends_on: [api] api: build: ./api environment: DATABASE_URL: postgres://user:pass@db:5432/app db: image: postgres:16 environment: POSTGRES_PASSWORD: pass volumes: - pgdata:/var/lib/postgresql/datavolumes: pgdata:web, api and db join a default network. The API connects to the DB via hostname 'db'. The pgdata named volume persists the database across down/up cycles.
In production
- Single-host deployments and local dev get a reproducible stack from one file.
- Overrides (docker-compose.override.yml) differ per environment while the base stays clean.
- CI uses compose to spin up ephemeral dependencies (Redis, Postgres) for tests.
- Readiness is handled with healthcheck + condition in depends_on for ordered startup.
Best practices
- Use named volumes for databases so data survives down/up.
- Set restart: unless-stopped on long-running services.
- Keep secrets out of the file — use env_file or $VARIABLE substitution.
- Pin image versions in the file.
Common mistakes
- Relying on default depends_on (wait-for-started, not wait-for-ready) for ordering.
- Putting credentials directly in YAML and committing them.
- Using docker compose down -v blindly in production (destroys volumes).
- Not using a version-pinned image, so behavior drifts.
Common issues
Service 'api' depends on 'db' which is unhealthydepends_on with condition: service_healthy but db has no healthcheck.
Add a healthcheck to the db service (e.g. pg_isready).
Cannot connect to the Docker daemon ... Is 'docker compose' project name invalid?Project name contains characters Docker rejects (e.g. uppercase or slashes).
Set an explicit project name: docker compose -p myapp up -d.
Network conflict: network name is already in useTwo compose projects generated the same network name.
Use distinct -p project names so networks are namespaced.
Debugging tips
- docker compose config to see the fully rendered, valid config.
- docker compose ps to see health and exit codes.
- docker compose logs --tail=50 to find the failing service's error.
- docker compose up --no-start then docker compose start for manual stepping.
Interview checkpoint
Hands-on lab
- Define a multi-service compose stack
- Wire services over a shared network
- Persist the database with a named volume
- Tear down safely without data loss
Orchestrate a Full Stack with Compose
40 min · intermediate
Quick quiz
Which command stops services and removes their named volumes?
By default, services in a Compose project communicate using...
docker compose up -d waits for databases to be ready by default.
Cheat sheet
docker compose up -dStart stack detacheddocker compose downStop + remove containersdocker compose down -vAlso remove volumesdocker compose psService statusdocker compose logs -fStream logsdocker compose configValidate + render config