Docker 50 🐳 Docker Cleanup Automation: docker system prune, Image Pruning, and Disk Space Audits
A Docker host accumulates garbage. The stopped containers linger, the dangling images pile up, the build cache grows, and the unused volumes sit idle. The disk fills slowly, and then suddenly the builds fail, the pulls fail, and the daemon stops responding. The cleanup is not a one-time task; it is the ongoing maintenance. The docker system prune and the related commands are the tools, and the automation is the discipline that keeps the host healthy. The audit comes first — you must know what is consuming the space before you can reclaim it — and the pruning is the removal. The cron job or the systemd timer runs the cleanup on the schedule, and the host stays lean.
The pruning commands form a hierarchy. The docker container prune removes the stopped containers, the docker image prune removes the unused images, the docker volume prune removes the unused volumes, and the docker builder prune removes the build cache. The docker system prune is the shortcut that runs the container, the network, the image, and the build cache pruning in the single command . The volumes are excluded by default, and the --volumes flag includes them . The -a flag extends the image pruning from the dangling images only to all the unused images .
The distinction between the dangling and the unused is the critical. A dangling image is the one that has no tag and no container reference — the intermediate layers from the builds that were replaced . The docker image prune without the -a removes only the dangling images. The -a flag removes every image that no container references, including the tagged images that are not currently used by a running or stopped container . The -a is the aggressive, and it means the next docker run re-pulls the image.
The disk space audit is the docker system df. The command shows the total, the active, the size, and the reclaimable for the images, the containers, the local volumes, and the build cache . The -v flag shows the per-object detail, and the --format "json" produces the machine-readable output for the scripts . The audit is the first step, and the RECLAIMABLE column is the potential saving.
This chapter covers three areas. First, why the cleanup automation exists — the disk-exhaustion problem and the audit-first principle. Second, the pruning commands — the docker system prune, the docker image prune, the docker builder prune, and the filters. Third, the automation — the cron job, the systemd timer, the third-party containers, and the safety patterns. The chapter ends with a complete example session, a quick reference, best practices, common pitfalls, real-world examples, and diagrams showing the pruning hierarchy.
Key point: The docker system prune removes the stopped containers, the unused networks, the dangling images, and the build cache. The -a flag extends to all unused images, and the --volumes flag includes the volumes. The docker system df audits the disk usage before the pruning. The --filter "until=24h" restricts the pruning to the old resources, and the --force skips the confirmation. The cron job automates the cleanup, and the docker image prune -f is the safe default.
Why the cleanup automation exists
The disk-exhaustion problem. The Docker host accumulates the data with every build, every pull, and every run. The dangling images from the rebuilds, the stopped containers from the crashes, the build cache from the layers, and the unused volumes from the removed containers. The disk fills slowly and then suddenly. The docker system df shows the reclaimable, and the docker system prune reclaims it .
The audit-first problem. The pruning without the audit is the blind. The docker system df shows what is consuming the space, and the docker system df -v shows the per-object detail . The audit identifies the large images, the old volumes, and the bloated build cache. The pruning is the removal, but the audit is the diagnosis .
The dangling-versus-unused problem. The dangling image is the orphan, and the unused image is the tagged but the unreferenced. The docker image prune removes the dangling, and the docker image prune -a removes the unused . The -a is the aggressive, and it means the re-pull. The distinction determines the safety of the cleanup.
The volume problem. The volumes are the persistent data, and the docker system prune does not remove them by default . The --volumes flag includes the anonymous volumes, and the named volumes are the explicit. The volume pruning is the dangerous, and the docker volume prune is the separate command for the deliberate removal.
The filter problem. The --filter "until=24h" restricts the pruning to the resources older than the 24 hours . The filter is the safety net: it prevents the removal of the images that were just built, the containers that just stopped, and the volumes that are actively used. The until filter accepts the duration strings, the Unix timestamps, and the date formats .
The trade-off. The aggressive pruning reclaims the space and forces the re-pull and the rebuild. The conservative pruning leaves the space and keeps the cache. The trade-off is between the disk space and the build speed, and the filter is the balance.
a. The audit with docker system df
The docker system df shows the disk usage by the type:
docker system df
The output:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 21 21 8.797GB 460.6MB (5%)
Containers 24 24 565MB 0B (0%)
Local Volumes 8 8 123MB 0B (0%)
Build Cache 20 0 922.7MB 922.7MB
The RECLAIMABLE is the potential saving, and the SIZE is the total .
The verbose. The -v flag shows the per-object detail:
docker system df -v
The output lists the individual images, the containers, and the volumes with the sizes and the shared/unique breakdown .
The JSON. The --format "json" produces the machine-readable:
docker system df --format "json"
The JSON is the script-friendly, and the jq parses the reclaimable.
The disk check. The du -sh /var/lib/docker shows the total, and the docker info | grep "Docker Root Dir" shows the location .
b. The pruning commands
The docker system prune. The command removes the stopped containers, the unused networks, the dangling images, and the build cache .
docker system prune
docker system prune -a
docker system prune -a --volumes
docker system prune -f
docker system prune --filter "until=24h"
The -a includes the unused images, the --volumes includes the anonymous volumes, the -f skips the confirmation, and the --filter restricts the scope .
The docker image prune. The command removes the unused images:
docker image prune
docker image prune -a
docker image prune -a --filter "until=24h"
docker image prune -a --filter "label=deprecated"
The -a removes all the unused, and the --filter restricts by the time or the label .
The docker builder prune. The command removes the build cache:
docker builder prune
docker builder prune -a
docker builder prune --filter "until=24h"
docker builder prune --keep-storage 10GB
The -a removes all the unused cache, and the --keep-storage keeps the specified amount .
The docker container prune. The command removes the stopped containers:
docker container prune
docker container prune --filter "until=24h"
The docker volume prune. The command removes the unused volumes:
docker volume prune
docker volume prune --filter "label=temp"
The volume pruning is the dangerous, and the --filter is the safety .
c. The automation
The cron job. The /etc/cron.daily/docker-prune script:
#!/bin/bash
docker container prune -f
docker volume prune -f
docker image prune -f
The chmod +x and the cron runs it daily .
The crontab. The user crontab:
# The daily safe cleanup
0 2 * * * /usr/bin/docker system prune -f
# The weekly deep cleanup
0 3 * * 0 /usr/bin/docker system prune -a --filter "until=168h" -f
The 0 2 * * * is the daily at the 2 AM, and the 0 3 * * 0 is the weekly on the Sunday .
The systemd timer. The modern alternative:
[Unit]
Description=The Docker cleanup
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
The OnCalendar=daily and the Persistent=true run the missed jobs .
The third-party containers. The clockworksoul/docker-gc-cron and the servivum/docker-host-cleanup run the cleanup on the schedule:
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-e CRON="0 0 * * *" \
clockworksoul/docker-gc-cron
The CRON environment variable sets the schedule, and the container mounts the Docker socket .
The safety patterns. The --filter "until=24h" prevents the removal of the fresh resources. The docker image prune -f is the safe default. The docker system prune -a --volumes is the dangerous, and the --dry-run is not supported in all the versions .
Complete Example Session
# ============================================
# PART 1: THE AUDIT
# ============================================
docker system df
# TYPE TOTAL ACTIVE SIZE RECLAIMABLE
# Images 21 21 8.797GB 460.6MB (5%)
# Containers 24 24 565MB 0B (0%)
# Local Volumes 8 8 123MB 0B (0%)
# Build Cache 20 0 922.7MB 922.7MB
# ============================================
# PART 2: THE VERBOSE AUDIT
# ============================================
docker system df -v
# The per-object detail.
# ============================================
# PART 3: THE BASIC PRUNE
# ============================================
docker system prune
# WARNING! This will remove:
# - all stopped containers
# - all networks not used by at least one container
# - all dangling images
# - all dangling build cache
# ============================================
# PART 4: THE AGGRESSIVE PRUNE
# ============================================
docker system prune -a
# The -a includes all unused images.
# ============================================
# PART 5: THE VOLUME PRUNE
# ============================================
docker system prune -a --volumes
# The --volumes includes the anonymous volumes.
# The named volumes are NOT removed.
# ============================================
# PART 6: THE IMAGE PRUNE
# ============================================
docker image prune
docker image prune -a
docker image prune -a --filter "until=24h"
# ============================================
# PART 7: THE BUILDER PRUNE
# ============================================
docker builder prune
docker builder prune -a
docker builder prune --keep-storage 10GB
# ============================================
# PART 8: THE CRON JOB
# ============================================
# /etc/cron.daily/docker-prune
#!/bin/bash
docker container prune -f
docker volume prune -f
docker image prune -f
# ============================================
# PART 9: THE CRONTAB
# ============================================
# The daily safe
0 2 * * * /usr/bin/docker system prune -f
# The weekly deep
0 3 * * 0 /usr/bin/docker system prune -a --filter "until=168h" -f
# ============================================
# PART 10: THE LFCS PIPELINE
# ============================================
# The audit
docker system df
# The safe cleanup
docker system prune -f
# The filtered cleanup
docker image prune -a --filter "until=24h" -f
# The build cache cleanup
docker builder prune -f
# The volume cleanup (careful)
docker volume prune -f
# The verify
docker system df
The ten parts show the audit, the verbose audit, the basic prune, the aggressive prune, the volume prune, the image prune, the builder prune, the cron job, the crontab, and the LFCS pipeline.
Quick Reference
The Prune Commands
| Command | The removes |
|---|---|
docker system prune | The containers, the networks, the dangling images, the build cache |
docker system prune -a | + all unused images |
docker system prune -a --volumes | + anonymous volumes |
docker image prune | The dangling images |
docker image prune -a | All unused images |
docker builder prune | The build cache |
docker container prune | The stopped containers |
docker volume prune | The unused volumes |
The Common Flags
| Flag | The purpose |
|---|---|
-a, --all | The all unused |
-f, --force | The skip confirmation |
--volumes | The include volumes |
--filter | The restrict scope |
The Filters
| Filter | The example |
|---|---|
until | --filter "until=24h" |
label | --filter "label=deprecated" |
label!= | --filter "label!=keep" |
The Audit Commands
| Command | The purpose |
|---|---|
docker system df | The disk usage |
docker system df -v | The verbose |
docker system df --format "json" | The JSON |
docker info | The root dir |
The Automation
| Tool | The command |
|---|---|
| Cron | 0 2 * * * docker system prune -f |
| Systemd | OnCalendar=daily |
| Container | docker-gc-cron |
Best Practices
✅ Do This:
# Audit before the prune
docker system df # ✅
# Use the filter for the safety
docker system prune --filter "until=24h" -f # ✅
# Use the image prune -f for the daily
docker image prune -f # ✅
# Use the builder prune for the cache
docker builder prune -f # ✅
# Use the cron for the automation
0 2 * * * /usr/bin/docker system prune -f # ✅
# Use the --keep-storage for the build cache
docker builder prune --keep-storage 10GB # ✅
❌ Don’t Do This:
# Don't prune the volumes without the review
docker system prune --volumes # the data loss // ❌
# Don't use the -a without the understanding
docker system prune -a # the re-pull required // ❌
# Don't prune without the audit
docker system prune # the blind // ❌
# Don't forget the -f in the cron
docker system prune # the interactive prompt in the cron fails // ❌
# Don't prune the active resources
docker image prune -a # the running containers are safe, the images are not // ❌
# Don't use the --volumes in the production
docker system prune --volumes # the dangerous // ❌
Common Pitfalls
| The pitfall | The why | The fix |
|---|---|---|
| The data loss | The --volumes | Use the docker volume prune separately |
| The re-pull | The -a | Use the until filter |
| The cron fails | The no -f | Add the --force |
| The space not reclaimed | The wrong command | Use the docker system df |
| The build cache grows | The no builder prune | Add the docker builder prune |
| The images removed | The -a without the filter | Use the --filter "until=24h" |
| The containers not removed | The running | Stop the containers first |
Real-World Examples
1. The Audit
docker system df
2. The Basic Prune
docker system prune -f
3. The Filtered Prune
docker system prune -a --filter "until=24h" -f
4. The Image Prune
docker image prune -a --filter "until=168h" -f
5. The Builder Prune
docker builder prune -a -f
6. The Volume Prune
docker volume prune -f
7. The Cron
0 2 * * * /usr/bin/docker system prune -f
8. The Keep Storage
docker builder prune --keep-storage 10GB
9. The JSON
docker system df --format "json"
10. The Complete
docker system prune -a --filter "until=168h" -f
Visual
The Pruning Hierarchy
┌──────────────────────────────────────────────────────────────┐
│ THE PRUNING HIERARCHY │
│ │
│ docker system prune │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ The stopped containers │ │
│ │ The unused networks │ │
│ │ The dangling images │ │
│ │ The build cache │ │
│ │ │ │
│ │ The -a adds: all the unused images │ │
│ │ The --volumes adds: the anonymous volumes │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ The individual commands: │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ docker container prune → the stopped containers │ │
│ │ docker image prune → the dangling images │ │
│ │ docker builder prune → the build cache │ │
│ │ docker volume prune → the unused volumes │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
The Dangling vs the Unused
┌──────────────────────────────────────────────────────────────┐
│ THE DANGLING vs THE UNUSED │
│ │
│ THE DANGLING: │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ The image with no tag and no container reference. │ │
│ │ The intermediate layers from the builds. │ │
│ │ │ │
│ │ docker image prune removes the dangling. │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ THE UNUSED: │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ The tagged image that no container references. │ │
│ │ The old version, the abandoned branch. │ │
│ │ │ │
│ │ docker image prune -a removes the unused. │ │
│ │ The re-pull is required for the next run. │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
The Audit
┌──────────────────────────────────────────────────────────────┐
│ THE AUDIT │
│ │
│ docker system df │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ TYPE TOTAL ACTIVE RECLAIMABLE │ │
│ │ Images 21 21 460.6MB (5%) │ │
│ │ Containers 24 24 0B (0%) │ │
│ │ Local Volumes 8 8 0B (0%) │ │
│ │ Build Cache 20 0 922.7MB │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ The RECLAIMABLE is the potential saving. │
│ The Build Cache is the usual culprit. │
│ │
└──────────────────────────────────────────────────────────────┘
The Automation
┌──────────────────────────────────────────────────────────────┐
│ THE AUTOMATION │
│ │
│ The cron: │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 0 2 * * * /usr/bin/docker system prune -f │ │
│ │ │ │
│ │ The daily at the 2 AM. │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ The container: │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ docker run -d │ │
│ │ -v /var/run/docker.sock:/var/run/docker.sock │ │
│ │ -e CRON="0 0 * * *" │ │
│ │ clockworksoul/docker-gc-cron │ │
│ │ │ │
│ │ The nightly at the midnight. │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ The --filter "until=24h" is the safety. │
│ │
└──────────────────────────────────────────────────────────────┘
Summary
| Item | Value |
|---|---|
docker system prune | The containers, the networks, the images, the cache |
-a | The all unused images |
--volumes | The anonymous volumes |
--filter | The restrict scope |
-f | The skip confirmation |
docker image prune | The dangling images |
docker builder prune | The build cache |
docker system df | The audit |
| The cron | The automation |
until=24h | The time filter |
Key takeaways:
- The
docker system pruneremoves the stopped containers, the unused networks, the dangling images, and the build cache. The-aflag extends the image pruning to all unused images, and the--volumesflag includes the anonymous volumes . - The
docker system dfaudits the disk usage before the pruning. TheRECLAIMABLEcolumn shows the potential saving, and the-vflag shows the per-object detail. The build cache is the usual culprit . - The dangling and the unused are different. The dangling image has no tag and no container reference. The unused image is the tagged but the unreferenced. The
docker image pruneremoves the dangling, and the-aremoves the unused . - The volumes are excluded from the system prune by default. The
--volumesflag includes the anonymous volumes, and the named volumes are the explicit. The volume pruning is the dangerous . - The
--filter "until=24h"restricts the pruning to the old resources. The filter prevents the removal of the fresh images, the just-stopped containers, and the active volumes . - The
--forceskips the confirmation. The cron and the script require the-f, because the interactive prompt fails in the non-interactive context . - The cron or the systemd timer automates the cleanup. The daily safe prune and the weekly deep prune are the common patterns. The third-party containers like the
docker-gc-cronprovide the packaged alternative . - The build cache is the separate command. The
docker builder pruneremoves the cache, and the--keep-storagekeeps the specified amount. The build cache is the large and the safe to remove .
Remember: The Docker cleanup is the ongoing maintenance. The docker system df audits the disk, and the docker system prune reclaims the space. The -a is the aggressive, and the --volumes is the dangerous. The --filter "until=24h" is the safety net, and the -f is the cron requirement. The result is the lean host that does not fill the disk, which is the foundation of the reliable operations.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!