DevOps Tutorial · Containers and Kubernetes · Lesson 18 of 25

Docker Compose

Run an app with its database and cache locally with one Docker Compose file: services, networks, volumes and health checks.

Create a free account to save this page, take notes and track your progress. Sign in

One file for the whole local stack

Docker Compose starts several containers together, with networking between them by service name:

services:
  api:
    build: .
    ports: ["8080:8080"]
    environment:
      DATABASE_URL: postgresql://app:app@db:5432/app    # "db" is the service name
      REDIS_URL: redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres:17
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
    volumes: ["pgdata:/var/lib/postgresql/data"]
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 5s
  cache:
    image: redis:7
volumes:
  pgdata:
docker compose up -d --build     # build and start everything
docker compose logs -f api
docker compose exec db psql -U app
docker compose down              # stop (add -v to delete volumes too)

Where Compose fits

Compose is ideal for local development and CI integration tests: everyone gets the same stack with one command. In production you'd use Kubernetes, ECS, Cloud Run, Azure Container Apps or similar, which add scheduling across machines, self-healing and rolling deployments.

Start order from depends_onTry it yourself
from graphlib import TopologicalSorter

depends_on = {"api": {"db", "cache"}, "worker": {"db", "cache"}, "db": set(), "cache": set()}
order = list(TopologicalSorter(depends_on).static_order())
print("start order:", order)

Output

start order: ['cache', 'db', 'api', 'worker']

Test yourself

In a Compose file, how does the api container reach the database?

  1. By the service name, e.g. db:5432
  2. Only via localhost:5432
  3. Through the host's public IP
  4. It can't without Kubernetes
Show answer

Answer: By the service name, e.g. db:5432

Compose puts services on a shared network where each service name resolves to its container.

Was this page helpful?