Overview

Docker Compose lets you define and run multi-container applications using a single YAML file. Instead of starting each container manually with docker run, you declare every service, network, and volume in one place and start everything with docker compose up.

Why Docker Compose Exists

A typical web application needs more than one container: a web server, a database, a cache, maybe a background worker. Running them individually means remembering long docker run commands with port mappings, environment variables, and volume mounts. Docker Compose solves this by centralizing configuration.

Install Docker Compose

Docker Compose v2 ships with Docker Desktop and modern Docker Engine. Verify it is available:

docker compose version

If you only have Docker Engine on Linux, install the Compose plugin from the Docker Compose official install guide.

Core Concepts

ConceptDescription
ServiceA container definition inside the Compose file, such as web or db
ProjectA group of services defined by one Compose file, with its own isolated network
VolumePersistent storage that survives container restarts
NetworkCompose creates a default network so services can reach each other by service name

Step 1: Create the Project Directory

mkdir my-compose-app
cd my-compose-app

Step 2: Write the Compose File

Create a file named compose.yaml:

services:
  web:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - db
    environment:
      DATABASE_URL: postgres://user:secret@db:5432/mydb

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: mydb
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:

This file defines two services. The web service builds from the current directory and connects to the db service using the hostname db, which Compose resolves automatically inside the project network.

Step 3: Start All Services

docker compose up -d --build

The -d flag runs containers in the background. The --build flag forces an image rebuild if the Dockerfile has changed.

Essential Docker Compose Commands

CommandPurpose
docker compose up -dStart all services in the background
docker compose downStop and remove containers and networks
docker compose down -vAlso remove named volumes
docker compose psList running services
docker compose logs -f webFollow logs for a specific service
docker compose exec web bashOpen a shell inside a running service
docker compose restart dbRestart a single service

Environment Variables and .env Files

Create a .env file in the project root:

POSTGRES_PASSWORD=supersecret

Then reference it in compose.yaml:

environment:
  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

Compose reads .env automatically. Keep this file out of version control.

Common Beginner Mistakes

ProblemCauseFix
Service cannot connect to databaseUsing localhost instead of the service nameUse the service name (e.g., db) as the hostname
Data disappears after downVolumes removed with -vOmit -v unless you intend to wipe data
Port already in useAnother process is using the host portChange the left side of the port mapping
Changes not reflectedImage cached from a previous buildRun docker compose up --build