Docker using too much disk space
In a hurry? whyfull checks for this and every other common cause in one command.
Docker keeps everything under /var/lib/docker: images, the writable layers of containers, volumes, build cache and container logs. On a busy build server or a host that has been running containers for months, this is often the single biggest directory on the disk.
The one rule: never delete files in /var/lib/docker by hand. Removing things from overlay2 directly corrupts images and containers in ways that are hard to recover from. Docker has a cleanup command for each kind of data, so use those.
See what's using the space
docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 41 6 18.2GB 15.9GB (87%)
Containers 9 6 412MB 3MB (0%)
Local Volumes 12 4 6.1GB 2.4GB (39%)
Build Cache 310 0 9.8GB 9.8GB
The RECLAIMABLE column is what the prune commands below can free. docker system df -v breaks it down per image, container and volume.
docker system df doesn't count container logs. Check those separately:
sudo du -h /var/lib/docker/containers/*/*-json.log | sort -h | tail
Clean up, safest first
Build cache. Layers kept to make later docker build runs faster. Nothing breaks without them: the next build is just slower.
docker builder prune -f # unused cache
docker builder prune -a -f # all of it
Stopped containers. Check that you don't need anything inside them first.
docker container prune -f
Unused images. -a removes every image that no container is using, not just untagged ones. They're downloaded again when something needs them.
docker image prune -a -f
Volumes. Volumes hold real data such as databases, so look before you prune. Since Docker Engine 23, docker volume prune only removes anonymous volumes. Add -a to include named volumes that no container is using.
docker volume ls -f dangling=true
docker volume prune -f
docker system prune does several of these in one go. Read what it lists before you confirm.
Container logs
With the default json-file log driver, Docker keeps everything a container prints, forever. A chatty container can write tens of gigabytes. To empty one container's log without stopping it:
sudo truncate -s 0 "$(docker inspect --format '{{.LogPath}}' my-container)"
To cap logs for good, add this to /etc/docker/daemon.json and restart Docker:
{
"log-driver": "json-file",
"log-opts": { "max-size": "50m", "max-file": "3" }
}
sudo systemctl restart docker
The limits only apply to containers created after the change, so recreate long-running containers to pick them up.
Move Docker to a bigger disk
If the root filesystem is simply too small, point Docker at another disk with "data-root": "/srv/docker" in daemon.json. Stop Docker, copy /var/lib/docker to the new place with rsync -aHAX, then start it again.