29 - Nettoyer Docker avant qu'il mange ton disque
Ce que tu vas apprendre
- Pourquoi Docker remplit ton disque silencieusement
- Comment diagnostiquer avec
docker system df - Les commandes prune pour tout nettoyer
- Le build cache et comment le gerer
- Automatiser le nettoyage avec un cron
Prerequisites
- Utiliser Docker depuis un moment (sinon tu n'as rien a nettoyer)
- Connaitre les volumes et les layers
"Disk full". Deux mots qui te reveillent a 3h du matin. J'ai reçu cette alerte un lundi. Le serveur de staging avait 100 Go de disque. Docker en occupait 74. Pas les donnees applicatives. Docker lui-meme. Des images de toutes les branches de feature qu'on avait testees depuis six mois, des conteneurs arretes jamais supprimes, un build cache de 20 Go.
Docker ne nettoie rien tout seul. Chaque docker build, chaque docker pull, chaque conteneur arrêté laisse des traces. Ca s'accumule.
Diagnostiquer avec docker system df
Avant de nettoyer, regarde ce qui prend de la place :
bashdocker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 47 3 12.4GB 11.2GB (90%)
Containers 23 3 1.2GB 1.1GB (95%)
Local Volumes 15 3 8.7GB 6.3GB (72%)
Build Cache 89 0 4.5GB 4.5GB (100%)
La colonne RECLAIMABLE est ce que tu peux récupérer. Dans cet exemple, 23 Go sur 27. C'est typique d'une machine de dev apres quelques mois.
Pour le détail par image :
bashdocker system df -v
Les coupables habituels
Images dangling : des images sans tag. Elles apparaissent quand tu rebuilds une image avec le meme tag. L'ancienne perd son tag et devient <none>:<none>. Elle existe toujours sur le disque.
bashdocker images -f dangling=true
Conteneurs arretes : chaque docker run créé un conteneur. Quand il s'arrêté, il reste sur le disque. Ses logs aussi. Tu as probablement des dizaines de conteneurs arretes dont tu ignores l'existence.
bashdocker ps -a --filter status=exited
Volumes orphelins : un volume créé par un conteneur qui n'existe plus. Le volume survit a son conteneur. C'est voulu (pour ne pas perdre de donnees), mais ca s'accumule.
bashdocker volume ls -f dangling=true
Build cache : chaque layer intermediaire du build est mise en cache. Sur un projet actif avec des builds frequents, le cache grossit vite. C'est souvent le poste le plus lourd.
Nettoyer chirurgicalement
Supprimer les images dangling :
bashdocker image prune
Supprimer les conteneurs arretes :
bashdocker container prune
Supprimer les volumes orphelins :
bashdocker volume prune
Supprimer le build cache :
bashdocker builder prune
Chaque commande demande confirmation. Ajoute -f pour forcer.
Le nucleaire : docker system prune
bashdocker system prune
Ca supprime les conteneurs arretes, les réseaux non utilises et les images dangling. C'est deja pas mal.
Pour aller plus loin :
bashdocker system prune -a --volumes
Le flag -a supprime toutes les images non utilisees par un conteneur en cours d'exécution. Pas seulement les dangling. Le flag --volumes inclut les volumes orphelins.
Attention : cette commande est destructive. Si tu as des images que tu veux garder mais qui ne sont attachees a aucun conteneur actif, elles disparaissent. Sur mon poste de dev, je la lance sans hesiter. Sur un serveur de prod, jamais.
Gerer le build cache
Le build cache est souvent le plus gros consommateur. Pour voir son contenu :
bashdocker builder prune --verbose
Pour limiter le cache a une taille :
bashdocker builder prune --keep-storage=5GB
Ca supprime les entrees les plus anciennes pour rester sous 5 Go.
Tu peux aussi configurer BuildKit pour limiter le cache globalement. Dans /etc/docker/daemon.json :
json{
"builder": {
"gc": {
"enabled": true,
"defaultKeepStorage": "10GB"
}
}
}
Ca déclenché un garbage collection automatique quand le cache dépassé 10 Go. C'est la méthode que je recommande. Tu gardes les avantages du cache sans l'accumulation infinie.
Supprimer les vieilles images par date
Pour supprimer les images créées il y a plus de 30 jours :
bashdocker image prune -a --filter "until=720h"
720 heures = 30 jours. Cette commande est parfaite pour un cron. Sur paltemps.fr, je l'utilise sur le serveur de staging ou les images des branches de feature s'accumulent.
Automatiser avec cron
Cree un cron qui nettoie chaque semaine :
bashcrontab -e
# Nettoyage Docker tous les dimanches a 3h du matin
0 3 * * 0 docker system prune -f --filter "until=168h" >> /var/log/docker-cleanup.log 2>&1
0 3 * * 0 docker builder prune -f --keep-storage=5GB >> /var/log/docker-cleanup.log 2>&1
Le flag -f évité la confirmation interactive. Le filtre until=168h (7 jours) protégé les images recentes.
Pour les volumes, sois plus prudent. Un docker volume prune automatique peut supprimer des donnees. Je préféré le faire manuellement apres vérification.
Lifecycle policies pour les registries
Si tu utilises un registry prive, les images s'accumulent la-bas aussi. La plupart des registries supportent des lifecycle policies :
- Docker Hub : pas de politique automatique sur le plan gratuit
- GitHub Container Registry : suppression via l'API ou les Actions
- AWS ECR : lifecycle policies natives (garder les N dernières images, supprimer apres X jours)
La stratégie que j'applique : garder les 10 derniers tags de chaque image, et les tags correspondant aux branches main/develop. Tout le reste est supprime apres 30 jours.
Résumé
- Docker ne nettoie rien automatiquement : images, conteneurs, volumes et cache s'accumulent
docker system dfmontre ce qui prend de la placedocker system prune -a --volumeslibéré le maximum d'espace (avec prudence)- Le build cache est souvent le plus gros consommateur : configure un garbage collection
- Automatise le nettoyage avec un cron sur les serveurs de staging et CI
Precedent : 28 - Healthchecks | Suivant : 30 - Registries