0 / 11 lessons — 0%
Lesson 06 / 11

Docker Compose

Real apps are rarely one container. An API, a database, maybe a cache — Compose describes that whole stack in one YAML file and brings it up or down as a single unit, instead of you juggling five separate docker run commands by hand.

# compose.yaml services: api: build: . ports: - "3000:3000" environment: DATABASE_URL: postgres://app:app@db:5432/app depends_on: - db db: image: postgres:16 environment: POSTGRES_USER: app POSTGRES_PASSWORD: app POSTGRES_DB: app volumes: - db-data:/var/lib/postgresql/data volumes: db-data:
docker compose up -d docker compose ps docker compose logs -f api docker compose down
host :3000 app-net (compose network) api :3000 db postgres:5432 db:5432
The api service reaches the db service by name — Compose resolves it on the shared app-net network.

Notice the API's DATABASE_URL points at host db, not an IP address. Services on the same Compose network reach each other by service name — Compose sets up that DNS resolution automatically.

Common gotcha: depends_on controls start order, not readiness. Postgres can still be booting when the API's first connection attempt fires. Add a healthcheck + condition: service_healthy, or retry logic in the app, for anything that matters.
Try it yourselfRun docker compose up -d with the file above, then docker compose exec api sh and try ping db from inside it. It resolves — no IP address in sight.