⚙️ Resource Limits
Why Limit Resources?
Without limits, a single container can consume all your CPU and memory. Imagine your MySQL container running a full table scan, eating up all the host's memory, causing Nginx to be OOM-killed — the entire service goes down.
Resource limits act as a "speed limiter" for each container, preventing a single container from dragging down the entire machine.
CPU Limits
bash
# --cpus: limit to at most 1.5 CPU cores
docker run -d --cpus=1.5 myapp
# --cpu-shares: proportional CPU allocation (default 1024)
docker run -d --cpu-shares=512 light-task # Low priority
docker run -d --cpu-shares=2048 heavy-task # High priority (4x weight)
# --cpuset-cpus: pin to specific CPU cores
docker run -d --cpuset-cpus="0,1" myapp # Use only cores 0 and 1
# View container CPU usage
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
NAME CPU % MEM USAGE / LIMIT
nginx 0.50% 12.3MiB / 512MiB
mysql 45.20% 1.2GiB / 2GiB
redis 0.10% 3.8MiB / 128MiBMemory Limits
bash
# Limit to at most 512MB memory
docker run -d --memory=512m myapp
# Set both soft and hard limits (soft triggers GC, hard triggers OOM kill)
docker run -d --memory=512m --memory-swap=1g myapp
# memory-swap = memory + swap, so swap is allocated 512m
# Disable swap (recommended for production)
docker run -d --memory=512m --memory-swap=512m --oom-kill-disable myapp
# ⚠️ Use --oom-kill-disable with caution: when memory is insufficient, the container won't be killed but may crash the host
# Check for OOM events
docker inspect --format='{{.State.OOMKilled}}' myapp
false
# View container memory usage
docker stats --no-stream myapp
NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
myapp 2.30% 256MiB / 512MiB 50.00% 1.2MB / 800kB 0B / 0B> ⚠️ Note: > ⚠️ Lesson learned: Java applications are especially prone to OOM — the JVM defaults to using 1/4 of system memory. When setting --memory for Java containers, remember to also set -Xmx in the application, otherwise the JVM may request memory beyond the container limit.
Disk I/O and Restart Policies
bash
# Limit disk write rate (10MB/s read, 5MB/s write)
docker run -d --device-read-bps=/dev/sda:10mb --device-write-bps=/dev/sda:5mb myapp
# Restart policies (always, on-failure, unless-stopped)
docker run -d --restart=always myapp # Auto-restart on crash
docker run -d --restart=unless-stopped myapp # Auto-restart unless manually stopped
docker run -d --restart=on-failure:5 myapp # Restart up to 5 times
# Configure resource limits in docker-compose.yml
cat > docker-compose.yml << 'EOF'
services:
web:
image: nginx:alpine
deploy:
resources:
limits:
cpus: "1.0"
memory: 256M
reservations:
cpus: "0.5"
memory: 128M
restart: unless-stopped
api:
build: ./api
deploy:
resources:
limits:
cpus: "2.0"
memory: 1G
restart: unless-stopped
EOF