Everyone Can Learn Program
中文 Start learning
Specialty · DevOpsLesson 3 of 5Free to read

Docker Compose · DevOps: Containers, CI and Kubernetes

How do you run an app that needs a database, a cache and a worker?

Course contents

Why you need it

Real apps are several programs: a web server, a database, a cache, a background worker. Starting each by hand with the right settings is error-prone. Docker Compose describes them all in one file, so the whole stack starts with one command on any machine.

The intuition

A compose.yaml lists services. Each one is a container:

services:
  web:
    build: .                 # build from the Dockerfile here
    ports:
      - "8080:8000"          # your machine's 8080 → the container's 8000
    environment:
      DATABASE_URL: postgres://shop:shop@db:5432/shop
    depends_on: [db]         # start db first
  db:
    image: postgres:16       # use a ready-made image
    volumes:
      - dbdata:/var/lib/postgresql/data
volumes:
  dbdata:
  • Services reach each other by service name: inside web, the database is at host db, not localhost (each container has its own localhost).
  • ports publishes a port to your machine: "HOST:CONTAINER".
  • A named volume keeps data when the container is recreated.
  • depends_on controls start order. (It waits for the container to start, not for the database to be ready to accept connections; add a healthcheck for that.)

docker compose up starts everything; docker compose down stops it.

YAML is indentation-sensitive: use spaces, never tabs.

Definition

Service

One container in a Compose file, with its image or build, ports, environment and volumes.

Volume

Storage that lives outside a container, so data survives when the container is replaced.

Port mapping

"8080:8000" forwards port 8080 on your machine to port 8000 inside the container.

Examples

A web app and its database

Run it in the lesson

Run it to see the start order and the parsed file.

services:
  web:
    build: .
    ports:
      - "8080:8000"
    environment:
      DATABASE_URL: postgres://shop:shop@db:5432/shop
    depends_on: [db]
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: shop
      POSTGRES_PASSWORD: shop
    volumes:
      - dbdata:/var/lib/postgresql/data
volumes:
  dbdata:
Step by step
  1. L3web is built from the Dockerfile in this folder.
  2. L5Open http://localhost:8080 on your machine to reach port 8000 in the container.
  3. L7The host is the service name db.
  4. L8db starts before web.
  5. L15Database files live in a named volume, so they survive a restart.

Common mistakes

localhost inside a container

In a container, localhost is that container itself. Use the other service's name (db, redis) as the host.

Data without a volume

A database without a volume loses everything when its container is recreated. Mount a named volume at its data folder.

Expecting depends_on to wait for readiness

depends_on only orders the starts. The app should retry its database connection, or use a healthcheck with condition: service_healthy.

Quick quiz

1. Inside the `api` container, what host reaches the `redis` service?

  1. Aredis
  2. Blocalhost
  3. C127.0.0.1
Show the answer

Answer: A

Compose gives every service a name that the others can use as a hostname.

2. `ports: ["5000:80"]`. Where do you point your browser?

  1. Ahttp://localhost:5000
  2. Bhttp://localhost:80
  3. Chttp://localhost:5080
Show the answer

Answer: A

HOST:CONTAINER: your machine's 5000 forwards to the container's 80.

Practice

3 exercises in three steps: predict what a program prints, change a program to meet a new requirement, then write one from scratch. Your code runs in the browser and is checked the moment you submit.

  1. PredictStart order

    In what order does Compose start these services? (When several are ready at once, it starts them alphabetically here.)

  2. Modifyweb can't reach the database

    web fails with "connection refused" when it talks to the database. Fix the database host in DATABASE_URL, and make sure db starts before web.

  3. WriteA three-service stack

    Write a Compose file with three services:

    • web: built from ., publishes 8080:8000, starts after api
    • api: image shop-api:1.4, environment DB_HOST: db, starts after db
    • db: image postgres:16, with a named volume dbdata mounted at /var/lib/postgresql/data

    Declare the dbdata volume at the top level too.

Practise this lesson

Open the interactive lesson to edit and run these examples and solve the exercises with instant feedback. Free to start, no sign-up.

Interactive lessons open in order. If you have not done the earlier ones yet, you start at the course map.

Terms in this lesson

TermChineseDefinition
Docker ComposeDocker ComposeRuns several containers described in one YAML file.
Volume卷Storage that outlives a container.
YAMLYAMLAn indentation-based text format for configuration.