Docker Compose Guide
Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application's services, networks, and volumes. Then, with a single command, you create and start all the services from your configuration.
Understanding Docker Compose
Docker Compose simplifies the process of managing multi-container applications by allowing you to:
- Define your application's environment in a
docker-compose.yml
file - Create and start all services with a single command
- Manage the entire lifecycle of your application
- Scale services up or down as needed
Basic Concepts
Services
Services are the containers that make up your application. Each service runs a single container and is defined in the docker-compose.yml
file.
Networks
Networks enable communication between containers. Docker Compose automatically creates a network for your application.
Volumes
Volumes are used for persistent data storage. They allow data to persist even when containers are stopped or removed.
Docker Compose File Structure
A basic docker-compose.yml
file structure:
version: '3.8'
services:
service_name:
image: image_name
container_name: container_name
environment:
- KEY=value
ports:
- "host_port:container_port"
volumes:
- volume_name:/container/path
networks:
- network_name
depends_on:
- other_service
volumes:
volume_name:
networks:
network_name:
Common Configuration Options
Image and Build
services:
web:
# Use an existing image
image: nginx:latest
# Or build from Dockerfile
build:
context: ./web
dockerfile: Dockerfile
Environment Variables
services:
db:
environment:
- DB_NAME=myapp
- DB_USER=user
# Or use .env file
env_file:
- .env
Ports
services:
web:
ports:
- "80:80" # Host:Container
- "443:443"
Volumes
services:
db:
volumes:
# Named volume
- db_data:/var/lib/mysql
# Bind mount
- ./config:/etc/mysql/conf.d
volumes:
db_data:
Networks
services:
web:
networks:
- frontend
- backend
networks:
frontend:
backend:
Dependencies
services:
web:
depends_on:
- db
- redis
Common Use Cases
Web Application Stack
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./web:/usr/share/nginx/html
depends_on:
- api
api:
build: ./api
environment:
- DB_HOST=db
depends_on:
- db
db:
image: postgres:latest
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Development Environment
version: '3.8'
services:
dev:
build:
context: .
target: development
volumes:
- .:/app
- /app/node_modules
ports:
- "3000:3000"
command: npm run dev
Best Practices
-
Version Control
- Always specify the Compose file version
- Keep your Compose files in version control
- Use
.env
files for environment-specific variables
-
Security
- Never commit sensitive data to version control
- Use secrets management for sensitive data
- Limit container capabilities
-
Resource Management
- Set resource limits for containers
- Use health checks
- Implement logging strategies
-
Organization
- Use meaningful service names
- Group related services
- Keep configurations modular
Common Commands
# Start services
docker-compose up
# Start in detached mode
docker-compose up -d
# Stop services
docker-compose down
# View logs
docker-compose logs
# Scale services
docker-compose up -d --scale service=3
# View running services
docker-compose ps
# Execute command in service
docker-compose exec service_name command
Troubleshooting
Common Issues
-
Container Won't Start
- Check logs:
docker-compose logs service_name
- Verify environment variables
- Check port conflicts
- Check logs:
-
Network Issues
- Ensure services are on the same network
- Check service names are correct
- Verify port mappings
-
Volume Issues
- Check volume permissions
- Verify paths are correct
- Ensure data persistence
Debugging Tips
- Use
docker-compose config
to validate your configuration - Enable debug mode with
COMPOSE_DEBUG=1
- Use
docker-compose ps
to check service status - Inspect networks with
docker network inspect
Advanced Topics
Scaling Services
services:
worker:
image: worker:latest
deploy:
replicas: 3
Health Checks
services:
web:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
Custom Networks
services:
web:
networks:
frontend:
ipv4_address: 172.16.238.10
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 172.16.238.0/24