Objectif
Diagnostiquer et remettre en service un conteneur Docker qui redémarre en boucle en préservant les logs et l’état, en identifiant le code de sortie, l’OOM ou la dépendance responsable, puis en corrigeant la cause avant de réactiver une politique de restart automatique.
Prérequis
- Nom/ID du conteneur ou service Compose et heure de début de la boucle.
- Accès Docker administrateur sur l’hôte.
- Fichier Compose ou commande de déploiement d’origine.
- Connaissance des volumes persistants et dépendances externes : base, DNS, proxy, certificats.
- Capacité à arrêter temporairement le conteneur pendant le diagnostic.
Procédure pas à pas
Capturer l’état avant modification
Listez les conteneurs avec leur statut et nombre de redémarrages. Inspectez ensuite le conteneur afin de relever ExitCode, OOMKilled, Error, StartedAt, FinishedAt et la restart policy. Ces éléments orientent immédiatement vers crash applicatif, OOM ou configuration.
docker ps -a --no-trunc
docker inspect <CONTAINER> --format '{{json .State}}'
docker inspect <CONTAINER> --format '{{json .HostConfig.RestartPolicy}}'
- Le code de sortie et la politique de restart sont connus.
Lire les logs autour du premier crash
Affichez les logs avec timestamps et limitez la fenêtre à l’incident. Cherchez la première erreur plutôt que les centaines de redémarrages suivants. Si l’application logue uniquement dans un fichier de volume, capturez aussi ce fichier.
docker logs --timestamps --tail 200 <CONTAINER>
docker logs --since 30m <CONTAINER>
- Une erreur applicative ou de dépendance est identifiée ou l’absence de log est constatée.
Neutraliser temporairement la boucle
Pour diagnostiquer sans redémarrages permanents, modifiez temporairement la restart policy ou arrêtez le service selon votre méthode de déploiement. Conservez la valeur précédente pour rollback. Avec Compose, changez le fichier source plutôt qu’une modification manuelle qui serait écrasée au prochain deploy.
docker update --restart=no <CONTAINER>
docker stop <CONTAINER>
- Le conteneur reste arrêté pendant l’analyse et ne consomme plus de ressources en boucle.
Contrôler mémoire, disque et OOM
Vérifiez OOMKilled et les événements kernel. Contrôlez aussi l’espace disque, car une application peut quitter lorsqu’elle ne peut plus écrire ses données ou logs. Si une limite mémoire est définie, comparez-la au besoin réel et aux métriques avant crash.
docker inspect <CONTAINER> --format 'OOM={{.State.OOMKilled}} Exit={{.State.ExitCode}} Error={{.State.Error}}'
dmesg -T | grep -i -E 'oom|killed process' | tail -30
df -h
- Une saturation mémoire ou stockage est confirmée ou écartée.
Vérifier configuration, mounts et secrets
Comparez l’environnement et les volumes avec le Compose ou manifeste attendu. Une variable manquante, un secret expiré, un fichier de configuration invalide ou un volume non monté provoque souvent un exit immédiat. Ne copiez pas les secrets bruts dans le rapport.
docker inspect <CONTAINER> --format '{{json .Mounts}}'
docker inspect <CONTAINER> --format '{{json .Config.Env}}'
- Les volumes et paramètres requis existent au moment du démarrage.
Tester les dépendances externes
Depuis l’hôte ou un conteneur de diagnostic adapté, vérifiez DNS, port de base de données, API et certificat. Un restart loop peut être le symptôme d’un backend indisponible si l’application quitte volontairement quand sa dépendance manque.
getent hosts <DEPENDENCY>
nc -vz <DEPENDENCY> <PORT>
- Les dépendances nécessaires au démarrage sont joignables.
Reproduire sans restart automatique
Démarrez une fois le conteneur après correction, sans boucle automatique, et suivez les logs. Avec Compose, utilisez docker compose up pour observer le service au premier plan ou relancez uniquement le service concerné. L’objectif est de voir le premier crash, pas le centième.
docker start <CONTAINER>
docker logs -f <CONTAINER>
- Le conteneur reste Running ou produit une erreur unique exploitable.
Corriger la cause et redéployer depuis la source
Appliquez la correction dans le Dockerfile, Compose, secret manager ou configuration versionnée. Évitez les modifications ad hoc à l’intérieur d’un conteneur qui disparaîtront à la recréation. Si l’image est fautive, revenez à un tag/digest connu sain ou construisez une nouvelle image.
- Le correctif est reproductible au prochain déploiement.
Réactiver une restart policy adaptée et surveiller
Une fois stable, remettez la politique prévue. Docker prend en charge no, on-failure, always et unless-stopped selon le mode. Pour une application qui ne doit pas masquer des crashes répétés, on-failure avec un nombre de tentatives peut être préférable à une boucle infinie. Surveillez RestartCount après remise en service.
docker update --restart=unless-stopped <CONTAINER>
docker inspect <CONTAINER> --format 'Restarts={{.RestartCount}} Status={{.State.Status}}'
- Le service reste stable et le compteur ne continue pas d’augmenter.
Validation
La procédure est validée lorsque :
- Le conteneur reste Running pendant la période de validation et son RestartCount est stable.
- Le code de sortie/OOM ou la cause applicative initiale est documenté.
- Le correctif est présent dans la source de déploiement et non uniquement dans le conteneur.
- Les dépendances, volumes et ressources nécessaires sont disponibles.
Retour arrière
- Revenir à l’image/tag ou à la configuration Compose précédente connue saine.
- Restaurer la restart policy initiale seulement après avoir confirmé que cela ne recrée pas une boucle dangereuse.
- Conserver les volumes persistants ; ne les supprimez pas pour recréer le conteneur sans validation.
- Si la correction échoue, maintenir le service arrêté et restaurer le service précédent plutôt que multiplier les redémarrages.
Dépannage / erreurs fréquentes
- Exit 137/OOMKilled : analyser mémoire et limites avant d’augmenter arbitrairement.
- Exit immédiat sans logs : vérifier entrypoint, permissions, config et destination des logs.
- Service fonctionne à la main mais pas via Compose : comparer env_file, mounts, networks et commande.
- RestartCount continue d’augmenter après correction : vérifier que le conteneur réellement modifié est celui servi en production.
- Dépendance DNS instable : traiter DNS/réseau plutôt que changer la restart policy.