What is Docker Compose?
Docker Compose is a tool for defining and running multi-container Docker applications. It uses a YAML file to configure your application's services, networks, and volumes, then creates and starts all the services with a single command.
Key Concepts
1. docker-compose.yml
The configuration file that defines services, networks, and volumes for your application.
2. Services
Individual containers that make up your application (web server, database, cache, etc.).
3. Projects
A set of services that work together, identified by a project name.
Installation
Docker Compose is included with:
- Docker Desktop (Windows/Mac)
- On Linux:
sudo apt-get install docker-compose-plugin
Verify installation:
docker compose versionBasic Structure
Minimal docker-compose.yml:
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"Example (highlighted): Minimal docker-compose.yml
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"Core Components
1. Services Configuration
services:
webapp:
image: myapp:latest
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
volumes:
- ./app:/code
networks:
- app-network
db:
image: postgres:13
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- db_data:/var/lib/postgresql/data
networks:
- app-network
redis:
image: redis:alpine
networks:
- app-network2. Networks
networks:
app-network:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: 14503. Volumes
volumes:
db_data:
driver: local
driver_opts:
type: none
o: bind
device: ./postgres-data4. Secrets (for sensitive data)
secrets:
db_password:
file: ./secrets/db_password.txt
services:
db:
image: postgres
secrets:
- db_passwordEssential Commands
Basic Operations
# Start services in foreground
docker compose up
# Start in background
docker compose up -d
# Stop services
docker compose down
# View running services
docker compose ps
# View logs
docker compose logs
docker compose logs -f # Follow logs
docker compose logs service_name # Specific service
# Build images
docker compose build
# Pull images
docker compose pullManagement Commands
# Execute command in running container
docker compose exec service_name command
# Scale services
docker compose up --scale web=3 --scale worker=2
# Restart services
docker compose restart
# Pause/unpause
docker compose pause
docker compose unpause
# Remove containers and volumes
docker compose down -v
# View resource usage
docker compose topAdvanced Configuration
1. Build Context with Dockerfile
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
args:
BUILD_ENV: production
image: myapp:custom2. Environment Variables
services:
web:
image: nginx
environment:
- NGINX_HOST=localhost
- NGINX_PORT=80
env_file:
- .env
- .env.production3. Health Checks
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s4. Resource Limits
services:
web:
image: nginx
deploy:
resources:
limits:
memory: 512M
cpus: '0.50'
reservations:
memory: 256M
cpus: '0.25'5. Dependencies and Startup Order
services:
web:
image: nginx
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
db:
image: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5Real-World Examples
1. WordPress with MySQL
version: '3.8'
services:
db:
image: mysql:8.0
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpresspass
wordpress:
image: wordpress:latest
ports:
- "8000:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpresspass
depends_on:
- db
volumes:
db_data:2. Full-Stack Application
version: '3.8'
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
volumes:
- ./frontend:/app
- /app/node_modules
environment:
- REACT_APP_API_URL=http://localhost:8000/api
backend:
build: ./backend
ports:
- "8000:8000"
volumes:
- ./backend:/app
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/app
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
db:
image: postgres:13
environment:
POSTGRES_DB: app
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:alpine
volumes:
- redis_data:/data
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- frontend
- backend
volumes:
postgres_data:
redis_data:Development vs Production
Development Configuration
# docker-compose.dev.yml
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
volumes:
- .:/code
environment:
- DEBUG=true
command: python manage.py runserver 0.0.0.0:8000Production Configuration
# docker-compose.prod.yml
version: '3.8'
services:
web:
image: myapp:prod
ports:
- "80:8000"
environment:
- DEBUG=false
restart: unless-stopped
deploy:
replicas: 3Useful Features
1. Multiple Compose Files
# Override base configuration
docker compose -f docker-compose.yml -f docker-compose.prod.yml up2. Profiles
services:
web:
# ... normal config
dev-tools:
profiles: ["dev"]
image: dev-tools:latest
# ... development tools config3. Extensions and Reuse
# Use extension fields for reusable configurations
x-logging: &default-logging
options:
max-size: "10m"
max-file: "3"
services:
web:
image: nginx
logging: *default-loggingBest Practices
1. Security
services:
db:
image: postgres
# Don't run as root
user: postgres
# Read-only root filesystem where possible
read_only: true2. Efficiency
services:
app:
build:
context: .
# Use .dockerignore to exclude unnecessary files
# Share common base images3. Organization
# Use meaningful service names
services:
database: # instead of 'db'
image: postgres
cache:
image: redis
application:
build: .Troubleshooting Commands
# Check configuration
docker compose config
# See what would be created
docker compose up --dry-run
# Force rebuild
docker compose build --no-cache
# Remove all containers and images
docker compose down --rmi all
# Follow specific service logs
docker compose logs -f service_nameCommon Patterns
1. Service Discovery
Services can communicate using service names as hostnames.
2. Development Hot-Reload
Mount source code as volumes for live reloading.
3. Database Migrations
services:
migrations:
build: .
command: python manage.py migrate
depends_on:
db:
condition: service_healthyNext Steps
- Practice with simple multi-container applications
- Explore Docker Compose for different stacks (LAMP, MEAN, etc.)
- Learn about Docker Swarm for orchestration
- Study production deployment strategies
This covers the essential knowledge you need to work effectively with Docker Compose. Start with simple configurations and gradually incorporate more advanced features as needed!