Docker remplit le disque : diagnostiquer les logs et limiter leur taille proprement
Un serveur Docker peut fonctionner parfaitement pendant des semaines, puis tomber brutalement : base de données en lecture seule, mises à jour impossibles, conteneurs qui redémarrent ou SSH qui devient instable. La cause n’est pas toujours une grosse image. Un conteneur bavard peut remplir le disque avec ses journaux.
Le piège est connu : Docker utilise par défaut le pilote json-file et, sans option supplémentaire, la taille de ces fichiers n’est pas plafonnée. Voici comment confirmer le diagnostic, trouver le conteneur responsable et mettre en place une rotation sans supprimer les données Docker au hasard.
Commencer par confirmer la saturation
df -h
df -i
df -h affiche l’espace occupé en octets. df -i contrôle les inodes, c’est-à-dire le nombre d’entrées de fichiers disponibles. Un disque peut encore avoir quelques gigaoctets libres mais ne plus accepter de fichiers si tous ses inodes sont consommés.
Identifiez d’abord le système de fichiers qui contient le répertoire de données Docker, souvent /var/lib/docker sous Linux. Ne partez pas du principe que Docker est coupable : les sauvegardes, journaux système ou fichiers d’une autre application peuvent aussi remplir la partition.
Séparer images, volumes, couches et journaux
docker system df
docker system df -v
Ces commandes montrent l’espace géré par Docker pour les images, les conteneurs, le cache de construction et les volumes. Le mode verbeux détaille les objets. C’est utile pour voir si une accumulation d’images ou un volume explique la saturation.
Attention : la taille visible pour un conteneur correspond principalement à sa couche inscriptible. Elle ne suffit pas toujours à expliquer les fichiers de logs du pilote. Si df annonce une partition pleine mais que docker system df ne montre rien de comparable, inspectez les chemins des journaux.
Trouver le chemin de log d’un conteneur
docker inspect --format='{{.Name}} {{.HostConfig.LogConfig.Type}} {{.LogPath}}' <conteneur>
La sortie fournit le nom, le pilote de journalisation et le chemin géré par Docker. Pour mesurer ce fichier sans le modifier :
sudo du -h "$(docker inspect --format='{{.LogPath}}' <conteneur>)"
Répétez l’inspection sur les conteneurs suspects. Un fichier de plusieurs gigaoctets n’est pas forcément le seul problème : cinquante petits services non limités peuvent produire le même résultat.
Docker précise que les fichiers des pilotes json-file et local sont réservés à son daemon. Les ouvrir avec docker logs est normal ; les tronquer, déplacer ou supprimer avec des outils externes peut perturber le mécanisme de journalisation.
Identifier pourquoi le conteneur parle autant
docker logs --since 10m --tail 200 --timestamps <conteneur>
Limitez la période et le nombre de lignes. Lancer docker logs sans filtre sur un fichier énorme peut être lent et produire une sortie inutilisable.
Recherchez surtout les répétitions :
- connexion à une base refusée toutes les secondes ;
- service externe indisponible sans temporisation entre les tentatives ;
- mode debug laissé actif en production ;
- healthcheck trop fréquent et trop bavard ;
- exception prise dans une boucle infinie ;
- proxy qui journalise chaque requête avec un niveau de détail inutile.
La rotation protège le disque, mais elle ne corrige pas cette cause. Un service qui écrit des milliers d’erreurs reste probablement malade et peut aussi saturer le processeur, le réseau ou une plateforme de centralisation des logs.
Option 1 : utiliser le pilote local
Docker recommande le pilote local pour réduire le risque d’épuisement du disque. Il stocke les sorties standard dans un format interne optimisé, active la rotation et la compression par défaut, et conserve par défaut environ 100 Mo par conteneur : cinq fichiers de 20 Mo.
Dans un fichier Compose, la limite peut être rendue explicite :
services:
app:
image: mon-application:latest
logging:
driver: "local"
options:
max-size: "10m"
max-file: "3"
Avec cet exemple, le service conserve au maximum trois segments d’environ 10 Mo. Ajustez la rétention au débit de logs et au temps nécessaire pour diagnostiquer un incident. Une limite minuscule peut effacer les seules traces utiles avant que l’alerte soit traitée.
Option 2 : conserver json-file avec une rotation
Si un outil ou une contrainte impose json-file, configurez les mêmes limites :
services:
app:
image: mon-application:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Pour ce pilote, max-size fixe le seuil de rotation. max-file fixe le nombre de fichiers conservés et n’est utile que si max-size est également défini.
Définir un défaut pour tout le daemon Docker
Sur un hôte Linux, le choix global se fait généralement dans /etc/docker/daemon.json. Exemple :
{
"log-driver": "local",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Ne remplacez pas aveuglément un fichier existant : il peut déjà contenir la configuration du réseau, du stockage, d’un registre privé ou d’autres options. Fusionnez les clés dans un JSON valide et gardez une copie de la version précédente.
Un redémarrage du daemon est nécessaire pour charger cette configuration. Planifiez-le comme une opération de maintenance, car son impact dépend de l’installation, du système et des politiques de redémarrage des conteneurs.
Le détail qui piège : les anciens conteneurs ne changent pas
Modifier daemon.json ou le fichier Compose ne reconfigure pas magiquement les conteneurs existants. Docker applique les nouvelles options aux conteneurs créés ensuite. Les anciens conservent le pilote et les limites reçus lors de leur création.
Avec Compose, il faut donc recréer le service concerné pendant une fenêtre adaptée :
docker compose up -d --force-recreate <service>
Avant cette opération, vérifiez que les données persistantes sont réellement stockées dans des volumes ou des emplacements prévus, que la sauvegarde est exploitable et que l’interruption est acceptable. Recréer un conteneur ne doit jamais être la première occasion de découvrir que les données importantes vivaient uniquement dans sa couche interne.
Que faire si le disque est déjà à 100 % ?
En urgence, commencez par identifier le producteur. Si le service inonde le disque, l’arrêter peut stopper l’aggravation :
docker stop <conteneur>
Cette commande provoque une indisponibilité : confirmez le rôle du conteneur avant de l’utiliser. Ensuite, préparez sa recréation avec une rotation correcte. S’il est critique, l’extension temporaire du stockage ou le basculement vers une autre instance peut être plus sûr qu’une suppression précipitée.
Évitez trois réflexes dangereux :
- supprimer manuellement un fichier actif dans
/var/lib/docker; - lancer un
docker system prunesans examiner ce qui sera retiré ; - effacer un volume simplement parce qu’il est gros : il peut contenir la base de données.
Surveiller avant la prochaine panne
La rotation est une barrière, pas une supervision. Ajoutez au minimum :
- une alerte sur l’occupation de la partition ;
- un contrôle des inodes ;
- une détection des redémarrages répétés et des erreurs en boucle ;
- une rétention cohérente avec votre délai d’intervention ;
- un test de la procédure de restauration si le service stocke des données.
Pour un petit VPS, quelques dizaines de mégaoctets par conteneur peuvent suffire si les alertes sont réactives. Pour un service critique, il faudra peut-être centraliser les journaux hors de l’hôte et définir une politique plus longue.
En bref
Quand Docker remplit un disque, mesurez avant de nettoyer. Distinguez les images, les volumes, les couches et les logs ; trouvez le conteneur bavard ; corrigez l’erreur répétée ; puis appliquez une rotation explicite avec le pilote local ou json-file. Le bon résultat n’est pas seulement de récupérer de l’espace aujourd’hui, mais d’empêcher la même panne de revenir.
Pour faire contrôler un serveur ou sécuriser une application conteneurisée, la page Services & tarifs de FuretSplick permet de consulter les accompagnements proposés.
