| |

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

CommandThe removes
docker system pruneThe 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 pruneThe dangling images
docker image prune -aAll unused images
docker builder pruneThe build cache
docker container pruneThe stopped containers
docker volume pruneThe unused volumes

The Common Flags

FlagThe purpose
-a, --allThe all unused
-f, --forceThe skip confirmation
--volumesThe include volumes
--filterThe restrict scope

The Filters

FilterThe example
until--filter "until=24h"
label--filter "label=deprecated"
label!=--filter "label!=keep"

The Audit Commands

CommandThe purpose
docker system dfThe disk usage
docker system df -vThe verbose
docker system df --format "json"The JSON
docker infoThe root dir

The Automation

ToolThe command
Cron0 2 * * * docker system prune -f
SystemdOnCalendar=daily
Containerdocker-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 pitfallThe whyThe fix
The data lossThe --volumesUse the docker volume prune separately
The re-pullThe -aUse the until filter
The cron failsThe no -fAdd the --force
The space not reclaimedThe wrong commandUse the docker system df
The build cache growsThe no builder pruneAdd the docker builder prune
The images removedThe -a without the filterUse the --filter "until=24h"
The containers not removedThe runningStop 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

ItemValue
docker system pruneThe containers, the networks, the images, the cache
-aThe all unused images
--volumesThe anonymous volumes
--filterThe restrict scope
-fThe skip confirmation
docker image pruneThe dangling images
docker builder pruneThe build cache
docker system dfThe audit
The cronThe automation
until=24hThe time filter

Key takeaways:

  • The docker system prune removes the stopped containers, the unused networks, the dangling images, and the build cache. The -a flag extends the image pruning to all unused images, and the --volumes flag includes the anonymous volumes .
  • The docker system df audits the disk usage before the pruning. The RECLAIMABLE column shows the potential saving, and the -v flag 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 prune removes the dangling, and the -a removes the unused .
  • The volumes are excluded from the system prune by default. The --volumes flag 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 --force skips 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-cron provide the packaged alternative .
  • The build cache is the separate command. The docker builder prune removes the cache, and the --keep-storage keeps 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!