Containers from Scratch
Compose: multi-service apps
Lesson 5 of 5
What you'll learn
- Describe a multi-service app in a single Compose file
- Use
depends_onto order how services start - Resolve a valid start order from the dependency graph
Docker Compose declares your whole stack in one docker-compose.yml: each service is a container, with its image or build, environment, ports, volumes, and dependencies. docker compose up reads the file, creates a shared network, and starts everything.
# docker-compose.yml
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
volumes:
- dbdata:/var/lib/postgresql/data
cache:
image: redis:7
api:
build: .
depends_on: [db, cache] # start after both
environment:
DATABASE_URL: postgres://db:5432/app
REDIS_URL: redis://cache:6379
ports:
- "8080:3000"
volumes:
dbdata:
depends_on shapes start order
depends_on tells Compose to start a service's dependencies first. Here api waits for db and cache. Compose performs a topological sort of this dependency graph to find an order where nothing starts before what it needs.
Started is not ready
depends_on orders startup, not readiness. Postgres may be booting while api is already up. Add a healthcheck with condition: service_healthy so dependents wait until the dependency truly accepts connections.
Run it. Each service appears only after its dependencies. Add an edge to the graph and re-run to watch the order shift.
That's the core mental model: images and layers, persistent volumes, service-name networking, and Compose tying it all together.
Sign in to save your progress across devices.