| name | docker-compose |
| description | Expert guidance for Docker Compose including multi-container applications, service definitions, networks, volumes, environment variables, health checks, and orchestration. Use this when working with Docker Compose files and container orchestration. |
| tags | ["docker","docker-compose","containers","orchestration"] |
| color | cyan |
Docker Compose Expert Skill
You are an expert in Docker Compose for defining and running multi-container applications.
Core Concepts
Compose File Structure
services:
service1:
networks:
network1:
volumes:
volume1:
secrets:
secret1:
configs:
config1:
IMPORTANT: The version field is obsolete since Compose Specification. Modern Docker Compose automatically uses the latest specification.
Service Definition
Basic Service
services:
web:
image: nginx:latest
build:
context: ./web
dockerfile: Dockerfile.dev
container_name: my-web
restart: unless-stopped
ports:
- "8080:80"
- "8443:443"
environment:
ENV_VAR: value
DEBUG: "true"
env_file:
- .env
- .env.local
volumes:
- ./config:/etc/nginx/conf.d:ro
- web-data:/var/www/html
networks:
- frontend
- backend
depends_on:
- database
command: ["nginx", "-g", "daemon off;"]
user: "1000:1000"
Advanced Options
services:
app:
image: myapp:latest
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 1G
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
dns:
- 8.8.8.8
- 8.8.4.4
extra_hosts:
- "host.docker.internal:host-gateway"
labels:
com.example.description: "My application"
com.example.version: "1.0"
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
privileged: true
Networks
Network Types
networks:
frontend:
driver: bridge
backend:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
gateway: 172.28.0.1
host-network:
driver: host
overlay-net:
driver: overlay
attachable: true
external-net:
external: true
name: my-existing-network
Service Network Configuration
services:
web:
networks:
frontend:
ipv4_address: 172.28.0.10
aliases:
- web-server
- www
Volumes
Volume Types
volumes:
data-volume:
driver: local
driver_opts:
type: none
o: bind
device: /path/on/host
external-volume:
external: true
name: my-existing-volume
Volume Mounts
services:
app:
volumes:
- app-data:/app/data
- ./config:/app/config:ro
- /app/temp
- type: tmpfs
target: /app/cache
tmpfs:
size: 100m
Environment Variables
Methods
services:
app:
environment:
DATABASE_URL: postgres://user:pass@db:5432/mydb
DEBUG: "true"
env_file:
- .env
- .env.production
environment:
HOST_IP: ${HOST_IP:-0.0.0.0}
PORT: ${PORT:-8080}
.env File Example
POSTGRES_USER=admin
POSTGRES_PASSWORD=secret123
POSTGRES_DB=myapp
NODE_ENV=production
Dependencies & Startup Order
Basic Dependencies
services:
web:
depends_on:
- database
- cache
database:
image: postgres:14
With Health Checks (v2.1+)
services:
web:
depends_on:
database:
condition: service_healthy
cache:
condition: service_started
database:
image: postgres:14
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
interval: 10s
timeout: 5s
retries: 5
Build Configuration
Simple Build
services:
app:
build: ./app
Advanced Build
services:
app:
build:
context: ./app
dockerfile: Dockerfile.prod
args:
- BUILD_VERSION=1.0.0
- NODE_ENV=production
target: production
cache_from:
- myapp:cache
labels:
- "com.example.version=1.0"
shm_size: '2gb'
Common Patterns
Web Application Stack
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
depends_on:
- app
networks:
- frontend
app:
build: ./app
environment:
DATABASE_URL: postgres://user:pass@db:5432/myapp
REDIS_URL: redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
networks:
- frontend
- backend
db:
image: postgres:14
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: myapp
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "user"]
interval: 10s
networks:
- backend
cache:
image: redis:alpine
networks:
- backend
networks:
frontend:
backend:
volumes:
db-data:
Development vs Production
services:
app:
image: myapp:latest
environment:
NODE_ENV: ${NODE_ENV:-development}
services:
app:
build:
context: .
target: development
volumes:
- ./src:/app/src
command: npm run dev
services:
app:
restart: always
deploy:
replicas: 3
resources:
limits:
memory: 1G
Usage:
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Commands
Basic Operations
docker-compose up
docker-compose up -d
docker-compose up --build
docker-compose up --force-recreate
docker-compose stop
docker-compose down
docker-compose down -v
docker-compose down --rmi all
docker-compose ps
docker-compose ps -a
docker-compose top
docker-compose logs
docker-compose logs -f
docker-compose logs -f app
docker-compose logs --tail=100 app
docker-compose exec app bash
docker-compose exec app ls -la
docker-compose exec -u root app sh
docker-compose run app npm install
docker-compose run --rm app pytest
docker-compose up -d --scale app=3
docker-compose config
docker-compose config --services
docker-compose config --volumes
Build & Images
docker-compose build
docker-compose build app
docker-compose build --no-cache
docker-compose pull
docker-compose pull app
docker-compose push
Advanced
docker-compose restart
docker-compose restart app
docker-compose pause
docker-compose unpause
docker-compose rm
docker-compose rm -f
docker-compose events
docker-compose events --json
docker-compose port app 8080
Best Practices
Security
- Don't hardcode secrets - Use environment variables or secrets
- Run as non-root - Specify user
- Use read-only mounts - Add
:ro to volumes
- Limit capabilities - Use
cap_drop and cap_add
- Use secrets for sensitive data (Docker Swarm)
Performance
- Use named volumes for data persistence
- Leverage build cache - Order Dockerfile commands properly
- Use health checks for dependencies
- Limit resource usage with deploy.resources
- Use Alpine images for smaller size
Development
- Use .dockerignore - Exclude unnecessary files
- Hot reload - Mount source code as volumes
- Separate dev/prod configs - Use compose file overrides
- Use profiles for optional services
Profiles
services:
app:
image: myapp
debug:
image: myapp
profiles:
- debug
command: ["node", "--inspect=0.0.0.0:9229", "app.js"]
test:
image: myapp
profiles:
- test
command: ["npm", "test"]
docker-compose up
docker-compose --profile debug up
docker-compose --profile debug --profile test up
Troubleshooting
Common Issues
| Issue | Solution |
|---|
| Port already in use | Change port mapping or stop conflicting service |
| Cannot connect between services | Check network configuration, use service names |
| Volume permission denied | Check user ID, use user: directive |
| Container keeps restarting | Check logs, verify command and health check |
| Build cache issues | Use --no-cache flag |
Debugging
docker-compose config --services
docker-compose ps
docker-compose logs service-name
docker inspect container-id
docker-compose exec app ping db
docker-compose exec app nslookup db
docker-compose exec app ls -la /path
docker-compose exec app env
Resources