Docker Compose Fundamentals
Docker Compose defines multi-container applications in a single YAML file.
Basic Structure
# docker-compose.yml
services:
web:
image: nginx:alpine
ports:
- "80:80"
api:
build: ./api
ports:
- "3000:3000"
environment:
- NODE_ENV=production
db:
image: postgres:16-alpine
volumes:
- db-data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: secret
volumes:
db-data:Essential Commands
# Start services
docker compose up
docker compose up -d # Detached mode
docker compose up --build # Rebuild images
# Stop services
docker compose down
docker compose down -v # Remove volumes too
# View status
docker compose ps
docker compose logs
docker compose logs -f api # Follow specific service
# Execute commands
docker compose exec api sh
docker compose exec db psql -U postgres
# Restart services
docker compose restart
docker compose restart apiService Configuration
Image vs Build
services:
# Use existing image
nginx:
image: nginx:alpine
# Build from Dockerfile
api:
build: ./api
# Build with options
app:
build:
context: .
dockerfile: Dockerfile.prod
args:
NODE_ENV: productionPort Mapping
services:
web:
ports:
- "8080:80" # HOST:CONTAINER
- "443:443"
- "127.0.0.1:3000:3000" # Localhost onlyEnvironment Variables
services:
api:
environment:
- NODE_ENV=production
- API_KEY=${API_KEY} # From shell/env file
# Or from file
env_file:
- .env
- .env.localComplete Examples
Web Application Stack
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
depends_on:
- api
api:
build: ./api
ports:
- "8080:8080"
environment:
- DATABASE_URL=postgres://postgres:secret@db:5432/app
depends_on:
- db
db:
image: postgres:16-alpine
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_DB: app
POSTGRES_PASSWORD: secret
volumes:
postgres-data:Development Environment
services:
app:
build: .
ports:
- "3000:3000"
volumes:
- .:/app # Bind mount for hot reload
- /app/node_modules # Preserve node_modules
command: npm run dev
environment:
- NODE_ENV=developmentNamed Volumes vs Bind Mounts
services:
db:
volumes:
# Named volume (managed by Docker)
- db-data:/var/lib/postgresql/data
app:
volumes:
# Bind mount (host path)
- ./src:/app/src
# Read-only bind mount
- ./config:/app/config:ro
volumes:
db-data: # Declare named volumeService Dependencies
services:
api:
depends_on:
- db
- redis
# With health checks
api:
depends_on:
db:
condition: service_healthy
redis:
condition: service_startedCommand Reference
| Command | Description |
|---|---|
up |
Create and start containers |
down |
Stop and remove containers |
ps |
List containers |
logs |
View output from containers |
exec |
Execute command in container |
build |
Build or rebuild services |
pull |
Pull service images |
restart |
Restart services |
- docker compose
- yaml
- services
- multi-container