Docker Compose: Complete Practical Guide
Complete guide to Docker Compose including multi-container applications, service definitions, networking, volumes, and production deployment.
# Docker Compose: Complete Practical Guide
Introduction
Docker Compose is a tool for defining and running multi-container Docker applications. Using a YAML file, you configure your application's services, networks, and volumes, then create and start all services with a single command.
Learning Objectives
By the end of this tutorial, you will be able to:
- Write docker-compose.yml files
- Define services, networks, and volumes
- Manage multi-container applications
- Use environment variables and configuration
- Deploy with Docker Compose in production
- Scale services and manage updates
Technical Background
Compose File Structure
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: example
networks:
app-network:
volumes:
db-data:Prerequisites
- Docker and Docker Compose installed
- Understanding of Docker concepts
Hardware and Software Requirements
| Component | Requirement | |-----------|-------------| | Docker Compose | v2+ |
Step-by-Step Implementation
Phase 1: Basic Compose File
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
volumes:
- ./code:/code
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: example
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:# Start all services
docker compose up -d
# Stop all services
docker compose down
# View logs
docker compose logs -f
# View status
docker compose ps
# Restart service
docker compose restart webPhase 2: Service Configuration
services:
web:
build: .
image: myapp:latest
command: python manage.py runserver 0.0.0.0:8000
ports:
- "8000:8000"
environment:
- DEBUG=1
- DATABASE_URL=postgres://user:pass@db:5432/mydb
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256MPhase 3: Networks and Volumes
networks:
frontend:
driver: bridge
backend:
driver: bridge
volumes:
db_data:
driver: local
cache_data:
driver: local
services:
web:
networks:
- frontend
api:
networks:
- frontend
- backend
db:
networks:
- backend
volumes:
- db_data:/var/lib/postgresql/dataPhase 4: Environment Variables
services:
web:
image: myapp:latest
env_file:
- .env
environment:
- DATABASE_URL=${DATABASE_URL}
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txtPhase 5: Production Deployment
# docker-compose.prod.yml
version: '3.8'
services:
web:
image: myregistry.com/myapp:prod
ports:
- "80:8000"
environment:
- NODE_ENV=production
restart: always
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3# Deploy with production config
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# Scale service
docker compose up -d --scale web=5
# Update service
docker compose pull web
docker compose up -d webExpected Output
- Multi-container application defined in compose file
- Services start and communicate correctly
- Networks and volumes configured
- Production deployment working
Verification Procedures
| Check | Command | Expected Result | |-------|---------|-----------------| | Services running | `docker compose ps` | All services healthy | | Logs accessible | `docker compose logs` | Service logs visible | | Network | `docker network ls` | Custom network exists | | Volume | `docker volume ls` | Data volume exists |
Troubleshooting Scenarios
| Issue | Diagnosis | Resolution | |-------|-----------|------------| | Service won't start | Configuration error | Check `docker compose config` | | Cannot connect between services | Network issue | Verify service names used as hostnames | | Data lost on restart | Volume not configured | Add volume mount to service | | Compose file invalid | YAML syntax error | Run `docker compose config` to validate |
Best Practices
- **Use named volumes:** For persistent data
- **Use healthchecks:** For service dependencies
- **Version pin images:** Use specific tags
- **Use .env files:** For environment-specific configuration
- **Separate prod/dev configs:** Use multiple compose files
- **Set restart policies:** For production reliability
Security Considerations
- **Use secrets:** For sensitive data
- **Limit resources:** Set CPU and memory limits
- **Run as non-root:** Use user directive in service
- **Scan images:** Before deployment
Conclusion
Docker Compose simplifies multi-container application management. By defining services, networks, and volumes in a single YAML file, you can spin up complex applications with one command and manage them consistently across development and production.
References
- Docker Compose Reference: https://docs.docker.com/compose/
- Compose File Reference: https://docs.docker.com/compose/compose-file/
- Docker Compose Best Practices: https://docs.docker.com/compose/production/