BuildBot

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_on to 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.

Topologically sort the start order

Run it. Each service appears only after its dependencies. Add an edge to the graph and re-run to watch the order shift.

Loading editor…

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.