Docker: reclaim disk space

updated 2026-07-01#docker#disque#maintenance

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.

shell
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 disk

If 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.

shell
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 days

Volumes: 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.

shell
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 volumes

Ballooning logs

By default, the json-file driver writes each container's logs to /var/lib/docker/containers/<id>/<id>-json.logwith no limit at all. One chatty container can fill your disk in weeks. Find the culprits:

shell
sudo find /var/lib/docker/containers -name '*-json.log' -exec du -h {} + | sort -hr | head

The real fix is to cap logs at the daemon level. In /etc/docker/daemon.json:

JSON
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
shell
sudo systemctl restart docker

Each 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.

shell
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