Storage Optimization
Docker objects accumulate silently -- old images, stopped containers, orphaned volumes, and build cache. Without proactive management, they consume gigabytes of disk space. This lesson covers how to monitor, analyze, and clean up safely.
Understanding What Uses Disk Space
flowchart TD
Disk["Docker Disk Usage"] --> Images["Images<br/>Old versions, dangling layers"]
Disk --> Containers["Stopped Containers<br/>Writable layers, logs"]
Disk --> Volumes["Volumes<br/>Database data, app state"]
Disk --> Cache["Build Cache<br/>Layer cache from builds"]
Disk --> Logs["Container Logs<br/>Unrotated log files"]
style Images fill:#e3f2fd,stroke:#1565c0
style Containers fill:#fff3e0,stroke:#ef6c00
style Volumes fill:#ffebee,stroke:#c62828
style Cache fill:#f5f5f5,stroke:#9e9e9e
style Logs fill:#fce4ec,stroke:#ad1457
Monitoring Disk Usage
# Quick summary
docker system df
# Detailed per-object breakdown
docker system df -v
# Host-level disk check
df -h /var/lib/docker
# Find the largest log files
sudo du -sh /var/lib/docker/containers/*/*-json.log | sort -rh | head -5
Safe Cleanup Strategy
Follow this order -- safest items first:
Step 1: Remove Build Cache (Safe)
docker builder prune -f
Step 2: Remove Stopped Containers (Safe)
docker container prune -f
Step 3: Remove Dangling Images (Safe)
docker image prune -f
Step 4: Remove All Unused Images (Careful)
# Removes any image not used by a running container
docker image prune -a -f
This also removes images you might need for rollback. Make sure they exist in your registry before pruning locally.
Step 5: Remove Unused Volumes (Dangerous)
# Check what volumes exist first
docker volume ls -f dangling=true
# Only then prune
docker volume prune -f
Volume prune deletes data for any volume not attached to a running container. If your database container is stopped, its data is deleted.
Cleanup Safety Table
| Command | What It Removes | Risk |
|---|---|---|
docker builder prune | Build cache | ✓ Safe |
docker container prune | Stopped containers | ✓ Safe |
docker image prune | Dangling images (<none>) | ✓ Safe |
docker image prune -a | All unused images | ⚠ Removes rollback images |
docker network prune | Unused networks | ✓ Safe |
docker volume prune | Unused volumes | ❌ Data loss risk |
docker system prune | Containers + images + networks + cache | ⚠ Check first |
docker system prune -a --volumes | Everything unused | ❌ Nuclear option |
Log Rotation (Prevent Disk Fills)
Container logs are the most common cause of unexpected disk fills. Configure rotation in /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Then restart Docker:
sudo systemctl restart docker
Existing containers keep their old settings -- recreate them to apply the new defaults.
Automated Cleanup for CI
For build servers, use time-based filtering to keep recent artifacts:
# Remove items older than 24 hours
docker system prune -f --filter "until=24h"
# Remove old images only
docker image prune -a -f --filter "until=48h"
Key Takeaways
- Run
docker system dfweekly to catch disk growth before emergencies. - Follow the cleanup order: cache → containers → dangling images → unused images → volumes.
- Never prune volumes without checking what exists and what is running.
- Configure log rotation in
daemon.jsonbefore anything else. - Use
--filter "until=24h"for safe automated CI cleanup.
What's Next
- Continue to Network and Compose Optimization.