Docker Fundamentals · Module 09 of 12

Docker Compose fundamentals

Define a multi-container application declaratively with services, networks, volumes, environment and lifecycle commands.

Learning objectives

By the end of this module, you should be able to:

  • Explain the different roles of a Dockerfile and compose.yaml.
  • Define services and manage them with docker compose.
  • Use Compose default networking and named volumes intentionally.

Dockerfile builds an image; Compose defines an application

A Dockerfile describes image build instructions. A Compose file describes running services and how they connect to networks, volumes, environment and published ports. A Compose service may reference a prebuilt image or build from a Dockerfile.

Compose is declarative

docker compose up reads the desired service definition and creates or reconciles containers, networks and volumes. docker compose down removes the application containers and default network; adding -v also removes declared named volumes and therefore deserves caution.

Service names become useful network identities

Compose normally creates a default network for the project. Services attached to that network can discover one another using service names. This reduces dependence on container IP addresses.

Worked examples

See the idea in practice.

Two-service Compose file

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
  cache:
    image: redis:7-alpine
  • web is published to the host.
  • cache is reachable by other services on the Compose network without a host port.

Common lifecycle commands

docker compose config
docker compose up -d
docker compose ps
docker compose logs
docker compose down
  • config renders/validates the resolved model.
  • up -d reconciles the stack in detached mode.
  • down removes the stack containers and network, but named volumes remain unless -v is used.
Hands-on lab

Lab — Define a reproducible two-service stack

Goal: Use Compose to start nginx and Redis, then prove both services are on one application network.

STEP 1

Create compose.yaml

mkdir -p ~/docker-fundamentals/compose && cd ~/docker-fundamentals/compose
cat > compose.yaml <<'EOF'
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
  cache:
    image: redis:7-alpine
EOF
STEP 2

Validate the model

docker compose config
STEP 3

Start the stack

docker compose up -d
docker compose ps
STEP 4

Verify frontend and shared application network

curl -I http://127.0.0.1:8080/
docker inspect "$(docker compose ps -q web)" --format '{{json .NetworkSettings.Networks}}'
docker inspect "$(docker compose ps -q cache)" --format '{{json .NetworkSettings.Networks}}'
docker compose exec cache redis-cli ping
STEP 5

Tear down safely

docker compose down

Verify

  • Both services reach running state.
  • Host port 8080 reaches nginx.
  • Both service containers are attached to the same Compose project network and Redis responds PONG.

Expected outcome

  • docker compose ps lists web and cache; the default network disappears after down.

If it fails

  • If the Compose command is missing, install the current Docker Compose plugin appropriate to your platform.
  • If port 8080 is used, change the published host port only; internal container ports remain unchanged.
Real-world connection

Compose provides a reproducible local integration environment and is also useful for small single-host deployments when its operational tradeoffs are acceptable.

Avoid these traps

Common mistakes

  • Confusing docker compose down with docker compose down -v.
  • Using container IP addresses instead of Compose service names.
  • Assuming depends_on by itself always means an application is ready to accept traffic.
Knowledge check

Can you explain it without looking back?

Open each answer only after you have tried to answer the question yourself.

1What is the key difference between Dockerfile and compose.yaml?

Dockerfile builds an image; Compose describes how one or more services run together.

2How do services normally discover one another on the default Compose network?

By service name using Docker-provided DNS.

3Why is docker compose down -v potentially destructive?

Because it removes named volumes declared/used by the Compose project, which can delete persistent data.