Chapter 19 • Production, Optimization & Security

Docker Maintenance & Disk Reclamation

Continuous development and automated CI/CD deployments quickly accumulate gigabytes of dangling image layers, orphaned anonymous volumes, and dormant BuildKit caches. Without regular hygiene, host disks eventually hit 100% capacity. In this chapter, learn how to audit disk consumption with docker system df, perform safe filtered purges, and schedule automated maintenance.

1. Auditing Docker Disk Space: docker system df

Before deleting anything, inspect where disk space is being allocated across the four Docker subsystems:

# Overview summary across images, containers, local volumes, and build cache:
docker system df

# Verbose breakdown showing size and reclaimable percentage per item:
docker system df -v
Resource TypeDescriptionReclaimable Criteria
ImagesRead-only OCI image layers stored in /var/lib/docker/overlay2/.Any image not referenced by a currently existing container.
ContainersWritable ephemeral container layers and stdout/stderr JSON logs.Any container in the exited or stopped state.
Local VolumesStateful directories stored in /var/lib/docker/volumes/.Any volume not mounted by a currently active or stopped container.
Build CacheBuildKit execution cache stages stored in /var/lib/docker/buildkit/.Intermediate compilation stages no longer needed for current builds.

2. Dangling Images vs Unused Images

Dangling Images (<none>:<none>)

Occurs when you build an updated version of an image with an existing tag (e.g. api:v1). Docker assigns the tag to the new image, leaving the older layers untagged as <none>. These are 100% safe to delete immediately:

docker image prune
Unused Images (-a Flag)

Images that possess valid tags (like postgres:16-alpine), but are not actively used by any running or stopped container. Deleting them reclaims massive space, but requires re-downloading layers next time:

docker image prune -a

3. Safe Time-Filtered Pruning

Avoid blindly running prune -a on production servers, as it purges recently cached layers that speed up daily builds. Use time-based filters (e.g. until=168h for 7 days):

# 1. Purge unused images older than 7 days (168 hours):
docker image prune -a --filter "until=168h" -f

# 2. Reclaim BuildKit compilation cache older than 48 hours:
docker builder prune --filter "until=48h" -f

# 3. Purge stopped containers older than 24 hours:
docker container prune --filter "until=24h" -f

4. The Nuclear Prune & The Volume Warning

Extreme Caution: The --volumes Flag

When you execute docker system prune -a --volumes, Docker deletes EVERY UNMOUNTED VOLUMEon the host machine. If you previously stopped your production database container for maintenance, its attached named volume will be permanently destroyed along with all persistent database data!

Automated Server Maintenance Cron Job

Schedule a weekly automated cleanup job in /etc/cron.weekly/docker-cleanup that reclaims disk space safely without endangering database volumes:

#!/bin/bash
# /etc/cron.weekly/docker-cleanup
# Safely reclaim dangling layers, old build caches, and stopped containers older than 14 days

/usr/bin/docker container prune -f --filter "until=336h"
/usr/bin/docker image prune -f --filter "until=336h"
/usr/bin/docker builder prune -f --filter "until=168h"
/usr/bin/docker network prune -f

Next Up: Container Orchestration & Kubernetes

In Chapter 20, discover when single-node Docker is enough and when your architecture needs to graduate to Kubernetes or Docker Swarm.

Chapter 20: Docker vs Kubernetes →

Explore Related Tools

Hand-picked utilities and calculators related to this tool.

Related Tools