Docker accumulates leftovers: old image versions after every update, stopped containers, build cache, unused volumes, and container logs. On a VPS with a modest disk, /var/lib/docker can quietly grow to fill it. Here’s how to see what’s using space and clean it up without deleting anything you need.
Step 1: see what’s using space
docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 34 9 12.4GB 9.1GB (73%)
Containers 12 9 310MB 45MB (14%)
Local Volumes 15 8 6.2GB 1.9GB (30%)
Build Cache 210 0 3.8GB 3.8GB
“Reclaimable” is what cleanup could remove. Details per item:
docker system df -v
And the full picture on disk, including logs:
sudo du -sh /var/lib/docker/* 2>/dev/null | sort -h
Step 2: remove the safe stuff
Stopped containers
docker container prune
Removes all stopped containers. Running ones are untouched. Make sure you don’t need anything inside a stopped container first (docker ps -a).
Dangling images
docker image prune
“Dangling” images are untagged layers — typically old versions left behind after docker pull or rebuilds (<none> in docker images). Always safe to remove.
All unused images
docker image prune -a
Removes every image not used by an existing container. This frees the most space. The catch: images for stacks that are currently stopped or not yet started will be downloaded again next time. Add a filter to keep recent ones:
docker image prune -a --filter "until=168h" # older than 7 days
Build cache
docker builder prune # dangling build cache
docker builder prune -a # all build cache
docker buildx prune --keep-storage 2GB # keep a budget for faster builds
On build servers and CI runners, build cache is often the biggest consumer.
Step 3: volumes — be careful
docker volume ls -f dangling=true
docker volume prune # anonymous unused volumes
docker volume prune -a # ALL unused volumes, including named ones
Volumes hold data — databases, uploads. A volume counts as “unused” when no container references it, which includes stacks you’ve temporarily brought down with docker compose down. Inspect the list before pruning, and back up anything that might matter. See Docker volumes.
The all-in-one command
docker system prune
Removes stopped containers, unused networks, dangling images and dangling build cache. Add flags for more:
docker system prune -a # + all unused images
docker system prune -a --volumes # + unused volumes (careful!)
docker system prune -f # no confirmation prompt (for scripts)
docker system prune -a without --volumes is a good routine cleanup: it removes things that can be re-downloaded or rebuilt, never data.
Container logs
Log files don’t show up in docker system df. Find large ones:
sudo sh -c 'du -h /var/lib/docker/containers/*/*-json.log' | sort -h | tail
Truncate one:
sudo truncate -s 0 /var/lib/docker/containers/<id>/<id>-json.log
And prevent it permanently with log limits in /etc/docker/daemon.json — see Docker logs.
Automate the cleanup
A weekly cron job that keeps a week of images:
# /etc/cron.d/docker-prune
30 4 * * 0 root docker image prune -af --filter "until=168h" > /dev/null && docker builder prune -af --filter "until=168h" > /dev/null
Or a systemd timer if you prefer — see the crontab guide.
Leave volumes out of automated pruning.
Still out of space?
- Images are big — use slim base images and multi-stage builds; see reducing Docker image size.
- Data in containers’ writable layers —
docker ps -sshows container sizes. Apps writing to their container filesystem should write to a volume instead. - Overlay2 leftovers after crashes — usually removed by prune; as a last resort, stop Docker and check
/var/lib/docker/overlay2with care (don’t delete folders by hand while Docker is running). - Docker isn’t the culprit — check the rest of the disk: disk full troubleshooting and finding large files.
- Move Docker’s data root to a bigger disk via
"data-root"indaemon.json.
Quick reference
| Command | Removes | Risk |
|---|---|---|
docker container prune |
Stopped containers | Low |
docker image prune |
Dangling images | None |
docker image prune -a |
Images not used by containers | Re-download later |
docker builder prune -a |
Build cache | Slower next build |
docker network prune |
Unused networks | None |
docker volume prune |
Unused anonymous volumes | Data loss possible |
docker system prune -a |
All of the above except volumes | Low |
docker system prune -a --volumes |
Everything unused | Data loss possible |
For a host with room to grow, our Docker VPS plans scale storage along with CPU and RAM.