Docker Compose — Scaling Services
Run multiple instances of a service for load distribution and redundancy.
Scale with –scale
docker compose up -d --scale api=3
This starts 3 instances of the api service:
NAME IMAGE STATUS PORTS
myapp-api-1 myapi:latest Up 2 minutes 0.0.0.0:3000->3000/tcp
myapp-api-2 myapi:latest Up 2 minutes
myapp-api-3 myapi:latest Up 2 minutes
Port Conflict
If your service maps a fixed host port, scaling fails:
services:
api:
image: myapi:latest
ports:
- "3000:3000" # Only one can bind to host port 3000!
Fix: Use a random host port or a load balancer:
services:
api:
image: myapi:latest
ports:
- "3000" # Random host port assigned per instance
Deploy Replicas
services:
api:
image: myapi:latest
deploy:
replicas: 3
docker compose up -d # Starts 3 instances automatically
Load Balancing with Nginx
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- api
api:
image: myapi:latest
deploy:
replicas: 3
expose:
- "3000"
nginx.conf:
upstream api {
server api:3000; # Compose DNS resolves to all instances
}
server {
listen 80;
location / {
proxy_pass http://api;
}
}
Compose DNS returns all container IPs for the service name, and Nginx round-robins between them.
Verify Scaling
docker compose ps
docker compose logs api # Shows logs from all instances
Scale Down
docker compose up -d --scale api=1 # Scale back to 1
Summary
| Feature | Config |
|---|---|
| CLI scaling | --scale api=3 |
| Deploy replicas | deploy: { replicas: 3 } |
| Port mapping | Use dynamic ports or load balancer |
| DNS | Service name resolves to all instances |
| Load balance | Nginx upstream or Traefik |
Quick Reference
| Item | Detail |
|---|---|
| –scale api=3 | Run 3 instances of api |
| deploy.replicas: 3 | Declarative scaling |
| Dynamic ports | ports: [‘3000’] (random host port) |
| DNS | Service name resolves to all replicas |
| Load balancer | Nginx upstream or Traefik |