Docker: reclaim disk space
Diagnose first
Before deleting anything, measure. docker system df breaks disk usage down by type (images, containers, volumes, build cache), and most importantly the RECLAIMABLE column: what you can safely get back.
docker system df # vue d'ensemble / overview
docker system df -v # détail par image/volume/conteneur / per-item detail
sudo du -h --max-depth=1 /var/lib/docker | sort -hr # qui pèse quoi sur le disque / what weighs what on diskIf overlay2/ dominates, it's images and layers. If volumes/ dominates, it's your data (be careful). If containers/ is huge, it's probably logs ballooning — see below.
Clean by target
Clean from least to most risky. Stopped containers and dangling images (the orphaned <none> left behind by rebuilds): harmless. Build cache: harmless too, it just gets rebuilt on the next build.
docker container prune # conteneurs arrêtés / stopped containers
docker image prune # images dangling uniquement / dangling images only
docker image prune -a # + toute image sans conteneur associé / + any image not used by a container
docker builder prune # build cache
docker builder prune --filter until=168h # cache de plus de 7 jours / cache older than 7 daysVolumes: the danger zone
Volumes hold your data: databases, uploads, configs. An "unused" volume is just one no container references right now — for instance because you ran docker compose down before cleaning up.
⚠️ Never run this command without listing and checking what it's about to destroy. A deleted volume is unrecoverable.
docker volume ls -f dangling=true # d'abord : lister les candidats / first: list the candidates
docker volume prune # ⚠️ supprime les volumes non référencés / deletes unreferenced volumesBallooning logs
By default, the json-file driver writes each container's logs to /var/lib/docker/containers/<id>/<id>-json.log — with no limit at all. One chatty container can fill your disk in weeks. Find the culprits:
sudo find /var/lib/docker/containers -name '*-json.log' -exec du -h {} + | sort -hr | headThe real fix is to cap logs at the daemon level. In /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}sudo systemctl restart dockerEach container is capped at 3 rotated 10 MB files. Note: this only applies to containers created after the restart — recreate existing ones (docker compose up -d --force-recreate) to benefit.
The big cleanup
⚠️ docker system prune -a --volumes combines everything: stopped containers, all unused images, the whole build cache, orphaned networks and every unreferenced volume — potentially your databases if the services happen to be down at that moment. Only use it if you can answer "yes" to: "can I afford to lose everything on this machine?". Otherwise, clean target by target as above.
docker system prune # version prudente : ni images taguées, ni volumes / safe version: no tagged images, no volumes
docker system prune -a --volumes # ⚠️ tout, y compris les volumes / everything, volumes included