Docker Compose
Overview
Docker Compose is a tool for defining and running multi-container applications. Instead of managing containers individually with multiple docker run commands, you define your entire application stack in a single YAML file.
This makes it easy to:
- Start/stop all services with one command
- Define relationships between containers
- Share configurations across team members
- Recreate consistent environments
Prerequisites
- Docker installed and configured (see Docker Setup)
Example: Web App with Database
Create a docker-compose.yml file:
services:
web:
image: nginx
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
This defines:
- A web server (nginx) on port 80
- A PostgreSQL database with persistent storage
- The web server waits for the database to start first
Start all services:
docker compose up -d
Stop and remove all services:
docker compose down
View running services and logs:
docker compose ps # List running services
docker compose logs # View logs from all services
docker compose logs -f web # Follow logs for specific service
Volumes
Named Volumes
Docker manages the storage location. Data persists even when containers are removed:
services:
db:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Bind Mounts
Map a host directory to a container directory. Changes on the host immediately appear in the container:
services:
web:
image: nginx
volumes:
- ./html:/usr/share/nginx/html
This is useful for development - edit files locally and see changes immediately.
Volume Commands
List all volumes:
docker volume ls
Show volume details:
docker volume inspect <name>
Remove a volume:
docker volume rm <name>
Remove all unused volumes:
docker volume prune
Networking
Containers in the same Compose file can communicate using service names as hostnames:
services:
web:
image: myapp
environment:
DATABASE_URL: postgres://db:5432/myapp
db:
image: postgres:15
The web container can reach the database at db:5432 (not localhost). Docker Compose automatically creates a network for all services.
Environment Variables
Pass environment variables to containers:
services:
app:
image: myapp
environment:
NODE_ENV: production
API_KEY: secret123
DATABASE_URL: postgres://db:5432/myapp
Or load from a file:
services:
app:
image: myapp
env_file:
- .env
Building Custom Images
Build images from a Dockerfile:
services:
app:
build: .
ports:
- "3000:3000"
Or specify build context and Dockerfile:
services:
app:
build:
context: ./app
dockerfile: Dockerfile.prod
ports:
- "3000:3000"