A brief look ahead: docker-compose

This concept is deliberately kept light — full depth belongs closer to when this course introduces a real database, later on.

The problem: more than one container, working together

Every container so far has run alone. A real app is often more than one piece — your app, plus a database it talks to — each one usually its own separate container, since an image is meant to be one focused, reusable definition, not a bundle of unrelated things. docker-compose is the tool for describing and starting several related containers together, as one unit.

docker-compose.yml: describing the pieces

services:
  app:
    build: .
    ports:
      - "8000:5000"
    environment:
      - DATABASE_URL=postgresql://db:5432/mydb
    depends_on:
      - db

  db:
    image: postgres:16
    environment:
      - POSTGRES_PASSWORD=devpassword
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:

Two services: app (built from the local Dockerfile, exactly as before) and db (using an existing, pre-built postgres image directly, no Dockerfile of its own needed). depends_on tells Compose to start db before app. Everything from earlier in this lesson appears here too, just written as YAML instead of flags: port mapping, environment variables, and — worth noticing specifically — a named volume, exactly like the one covered earlier, mounted at Postgres’s actual data directory. Without it, the database’s data would vanish every time this container gets recreated — the same ephemeral-filesystem problem from that section, just one Postgres restart away from actually happening here.

Starting everything together

docker compose up
docker compose up
click Run to see this pane's output

Running this streams interleaved startup logs from both containers, clearly labeled by service name. Worth noticing: app’s log line reaches the database at the hostname db — the service name from docker-compose.yml — not localhost or any IP address. Compose automatically gives each service a way to reach the others by name, on a shared network it sets up between them, without any manual network configuration.

Check your understanding
1/3

What problem does docker-compose solve that a single Dockerfile/docker run doesn't?