Container Resource Management
Setting resource limits (covered in Resource Limits) is only half the equation. You also need to monitor actual usage, adjust limits on running containers, and track disk consumption. This lesson covers the operational side of container resource management.
Live Monitoring with docker stats
docker stats is the real-time dashboard for container resource usage:
docker stats
Output:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a1b2c3d4e5f6 api 2.50% 180MiB / 512MiB 35.16% 1.2MB / 800kB 5MB / 0B 25
f6e5d4c3b2a1 db 0.80% 350MiB / 1GiB 34.18% 500kB / 1.5MB 50MB / 20MB 18
b2c3d4e5f6a1 cache 0.10% 50MiB / 256MiB 19.53% 200kB / 100kB 0B / 0B 4
Understanding the Columns
| Column | What It Shows | Watch For |
|---|---|---|
| CPU % | CPU usage relative to host capacity | Sustained 100%+ = throttling likely |
| MEM USAGE / LIMIT | Current memory / configured limit | Close to limit = OOM risk |
| MEM % | Memory as percentage of limit | Above 80% consistently = danger zone |
| NET I/O | Network bytes received / sent | Unexpected spikes = possible issue |
| BLOCK I/O | Disk reads / writes | High writes = possible logging issue |
| PIDS | Process count | Rapid increase = fork bomb risk |
Filtering and Formatting
# Monitor specific containers
docker stats api db cache
# No-stream: single snapshot (useful in scripts)
docker stats --no-stream
# Custom format
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}"
# JSON output (for piping to monitoring tools)
docker stats --no-stream --format '{{json .}}'
Use docker stats --no-stream in monitoring scripts and cron jobs. It prints one snapshot and exits, making it easy to parse and log.
Disk Usage with docker system df
docker system df shows how much disk space Docker is using across images, containers, and volumes:
docker system df
Output:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 15 5 3.2GB 1.8GB (56%)
Containers 8 5 200MB 120MB (60%)
Local Volumes 12 6 5.1GB 2.3GB (45%)
Build Cache - - 800MB 800MB
Detailed View
docker system df -v
This shows individual items with their sizes -- useful for finding the biggest offenders.
Reclaiming Space
# Remove stopped containers, unused networks, dangling images, and build cache
docker system prune
# Also remove unused volumes (careful -- data loss!)
docker system prune --volumes
# Remove only dangling images
docker image prune
# Remove only stopped containers
docker container prune
# Remove only unused volumes
docker volume prune
docker system prune --volumes deletes unused volumes, which may contain database data. Always verify which volumes are in use before running this command.
Updating Limits on Running Containers
docker update changes resource limits without restarting a container:
# Increase memory limit
docker update --memory=1g --memory-swap=1g api
# Change CPU limit
docker update --cpus=2.0 api
# Change restart policy
docker update --restart unless-stopped api
# Update multiple containers at once
docker update --memory=512m api worker scheduler
What Can Be Updated Live
| Setting | Flag | Requires Restart? |
|---|---|---|
| Memory limit | --memory | ❌ No |
| Memory + Swap | --memory-swap | ❌ No |
| CPU limit | --cpus | ❌ No |
| CPU shares | --cpu-shares | ❌ No |
| PID limit | --pids-limit | ❌ No |
| Restart policy | --restart | ❌ No |
| Block I/O weight | --blkio-weight | ❌ No |
docker update is invaluable during incidents. If a container is being OOM-killed, you can increase its memory limit immediately without downtime.
Resource Monitoring Patterns
Pattern 1: Quick Health Check Script
#!/usr/bin/env bash
# health-check.sh -- quick resource overview
echo "=== Container Resources ==="
docker stats --no-stream --format \
"table {{.Name}}\t{{.CPUPerc}}\t{{.MemPerc}}\t{{.PIDs}}"
echo ""
echo "=== Disk Usage ==="
docker system df
echo ""
echo "=== Containers with high memory (>80%) ==="
docker stats --no-stream --format '{{.Name}} {{.MemPerc}}' | \
awk '{gsub(/%/,"",$2); if ($2 > 80) print $1, $2"%"}'
Pattern 2: Log Resource Usage Over Time
#!/usr/bin/env bash
# log-stats.sh -- append stats to a log file every minute
LOG_FILE="/var/log/docker-stats.log"
while true; do
echo " $(date -Iseconds) " >> "$LOG_FILE"
docker stats --no-stream --format \
'{{.Name}},{{.CPUPerc}},{{.MemUsage}},{{.MemPerc}},{{.PIDs}}' \
>> "$LOG_FILE"
sleep 60
done
Pattern 3: Alert on High Memory
#!/usr/bin/env bash
# alert-memory.sh -- warn if any container exceeds 85% memory
THRESHOLD=85
docker stats --no-stream --format '{{.Name}} {{.MemPerc}}' | while read name pct; do
value=$(echo "$pct" | tr -d '%')
if (( $(echo "$value > $THRESHOLD" | bc -l) )); then
echo "WARNING: $name memory at $pct (threshold: ${THRESHOLD}%)"
# Add notification (email, Slack webhook, etc.)
fi
done
Container Events
docker events streams real-time events from the Docker daemon -- useful for monitoring container lifecycle:
# Watch all events
docker events
# Filter by container
docker events --filter container=api
# Filter by event type
docker events --filter event=oom --filter event=die --filter event=restart
# Time range (last hour)
docker events --since 1h
Key events to monitor:
| Event | Meaning | Action |
|---|---|---|
oom | Container hit memory limit | Increase limit or fix memory leak |
die | Container exited | Check exit code and logs |
restart | Container restarted | Monitor restart count for storms |
kill | Container was killed | Check who/what sent the signal |
Putting It All Together
flowchart TD
A["Set initial limits\n(docker run --memory --cpus)"] --> B["Monitor with\ndocker stats"]
B --> C{Issues?}
C -->|"OOM kills"| D["Increase memory\ndocker update --memory"]
C -->|"CPU throttling"| E["Increase CPU\ndocker update --cpus"]
C -->|"Disk full"| F["Clean up\ndocker system prune"]
C -->|"No issues"| G["Document limits\nand continue monitoring"]
D --> B
E --> B
F --> B
style A fill:#e3f2fd,stroke:#1565c0
style G fill:#e8f5e9,stroke:#2e7d32
style D fill:#fff3e0,stroke:#ef6c00
style E fill:#fff3e0,stroke:#ef6c00
style F fill:#ffebee,stroke:#c62828
Key Takeaways
docker statsis your real-time resource dashboard -- use--no-streamfor scripting.docker system dfreveals disk usage across images, containers, and volumes.docker updatechanges resource limits on running containers without restart -- invaluable during incidents.docker eventsstreams lifecycle events for monitoring OOM kills, crashes, and restarts.- Build monitoring scripts to catch high memory usage and disk pressure before they cause outages.
What's Next
- Continue to Understanding Docker Storage to learn how container filesystems and layers work.