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
| Concept | Description |
|---|---|
| Service | A container definition inside the Compose file, such as web or db |
| Project | A group of services defined by one Compose file, with its own isolated network |
| Volume | Persistent storage that survives container restarts |
| Network | Compose 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
| Command | Purpose |
|---|---|
docker compose up -d | Start all services in the background |
docker compose down | Stop and remove containers and networks |
docker compose down -v | Also remove named volumes |
docker compose ps | List running services |
docker compose logs -f web | Follow logs for a specific service |
docker compose exec web bash | Open a shell inside a running service |
docker compose restart db | Restart 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
| Problem | Cause | Fix |
|---|---|---|
| Service cannot connect to database | Using localhost instead of the service name | Use the service name (e.g., db) as the hostname |
Data disappears after down | Volumes removed with -v | Omit -v unless you intend to wipe data |
| Port already in use | Another process is using the host port | Change the left side of the port mapping |
| Changes not reflected | Image cached from a previous build | Run docker compose up --build |
