Docker Compose — What is Docker Compose
Docker Compose is a tool for defining and running multi-container Docker applications. You describe your entire application stack in a single YAML file, then bring everything up — or tear everything down — with one command.
The Problem Compose Solves
Imagine you’re building a web application that needs:
- A Node.js API server
- A PostgreSQL database
- A Redis cache
- An NGINX reverse proxy
Without Compose, you’d run four separate commands:
# Create a network
docker network create myapp
# Start PostgreSQL
docker run -d \
--name db \
--network myapp \
-e POSTGRES_PASSWORD=secret \
-v pgdata:/var/lib/postgresql/data \
postgres:16
# Start Redis
docker run -d \
--name cache \
--network myapp \
redis:7-alpine
# Start the API
docker run -d \
--name api \
--network myapp \
-e DATABASE_URL=postgres://postgres:secret@db:5432/app \
-e REDIS_URL=redis://cache:6379 \
-p 3000:3000 \
myapp-api:latest
# Start NGINX
docker run -d \
--name proxy \
--network myapp \
-p 80:80 \
-v ./nginx.conf:/etc/nginx/nginx.conf:ro \
nginx:alpine
That’s 5 commands with complex flags, volume mounts, environment variables, and network configuration. Now imagine doing this every day. Or sharing it with a teammate.
The Compose Solution
With Docker Compose, all of that becomes one file:
services:
proxy:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- api
api:
image: myapp-api:latest
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://postgres:secret@db:5432/app
REDIS_URL: redis://cache:6379
depends_on:
- db
- cache
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data
cache:
image: redis:7-alpine
volumes:
pgdata:
And one command to start everything:
docker compose up -d
Expected output:
[+] Running 5/5
✔ Network myapp_default Created
✔ Container myapp-db-1 Started
✔ Container myapp-cache-1 Started
✔ Container myapp-api-1 Started
✔ Container myapp-proxy-1 Started
One command to stop everything:
docker compose down
How Compose Works
┌─────────────────────────────────────────────┐
│ Developer Machine │
│ │
│ compose.yml ──→ Docker Compose CLI │
│ │ │
│ ▼ │
│ Docker Engine API │
│ │ │
│ ┌────────────┼────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │Container│ │Container│ │Container│ │
│ │ (web) │ │ (api) │ │ (db) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │
│ └────────────┴────────────┘ │
│ Compose Network │
└─────────────────────────────────────────────┘
Docker Compose:
- Reads your
compose.ymlfile - Translates each service definition into Docker API calls
- Creates networks, volumes, and containers
- Manages the lifecycle of all containers together
Think of Compose as a recipe book for your application. The compose.yml is the recipe — it describes what ingredients (images) you need, how to combine them (networks), and what to store (volumes). docker compose up is saying “make the dish.”
Declarative vs Imperative
Docker Compose uses a declarative approach — you describe what you want, not how to get there.
| Approach | Example | How it works |
|---|---|---|
| Imperative | docker run -d --name db postgres |
You tell Docker each step |
| Declarative | services: db: image: postgres |
You describe the desired state |
The declarative approach means:
- Reproducible — Same file, same result, every time
- Self-documenting — The YAML file IS the documentation
- Version-controlled — Track changes in Git
- Shareable — Anyone can run your stack with
docker compose up
Real-World Analogy
Think of Docker Compose like an orchestra conductor’s score.
- Each service is a musician (container)
- The compose.yml is the musical score (what to play)
docker compose upis the conductor raising the baton (start playing)docker compose downis the concert ending (everyone stops)- Networks are like sections (strings, brass, woodwinds talking to each other)
- Volumes are the music stands (persistent data)
Without a score, you’d have to tell each musician individually what to play. With a score, everyone knows their part and plays together.
What Compose Creates
When you run docker compose up, Compose creates:
| Resource | Naming Convention | Example |
|---|---|---|
| Network | <project>_default |
myapp_default |
| Container | <project>-<service>-<number> |
myapp-db-1 |
| Volume | <project>_<volume> |
myapp_pgdata |
The project name defaults to the directory name. If your compose.yml is in /home/user/myapp/, the project name is myapp.
Summary
| Concept | Detail |
|---|---|
| What | Tool for defining multi-container Docker apps |
| Format | YAML file (compose.yml) |
| Start | docker compose up -d |
| Stop | docker compose down |
| Approach | Declarative — describe desired state |
| Creates | Containers, networks, volumes |
| Project Name | Defaults to directory name |
Quick Reference
| Item | Detail |
|---|---|
| Docker Compose | Tool for multi-container Docker applications |
| compose.yml | YAML file defining services, networks, volumes |
| docker compose up -d | Start all services in background |
| docker compose down | Stop and remove all services |
| Declarative | Describe what you want, not how to do it |
| Project name | Defaults to current directory name |