E-NO
DevOps 10 min de lecture

Check-lists opérationnels pour les healthchecks Docker en production : guide pratique

calendar_today Publié : 2026-09-12
update Dernière mise à jour : 2026-09-12
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Check-lists opérationnels pour les healthchecks Docker en production : guide pratique ».

Introduction

Lorsqu'un service conteneurisé échoue en production, la première question est rarement « Qu'est-ce qui est cassé ? » mais « Comment savons-nous que c'est cassé ? » Les healthchecks Docker répondent à cette question en définissant une commande que le conteneur exécute périodiquement pour rapporter son état interne. Pourtant, de nombreuses équipes traitent le healthcheck comme une simple case à cocher dans le Dockerfile ou le fichier Compose, et ne découvrent ses angles morts qu'au moment d'un incident.

Cet article est une check-list opérationnelle pour les healthchecks Docker en production. Il s'adresse aux développeurs, ingénieurs DevOps et équipes techniques de startups qui exécutent des services dans Docker et ont besoin d'une méthode reproductible pour vérifier que ces services ne font pas que tourner, mais sont réellement sains. L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des variables d'environnement plutôt que des secrets, vérifier le résultat et documenter comment récupérer lorsque l'état attendu n'est pas atteint.

Chaque section combine un élément de check-list avec au moins une commande concrète, sa sortie attendue, les signaux d'échec courants et la décision de reprise qui en découle. La check-list est ordonnée approximativement comme vous aborderiez un système de production en opérations normales, puis pendant un incident.

Inventaire des versions et de l'environnement

Avant de toucher à quoi que ce soit, sachez exactement ce que vous exécutez. Un healthcheck ne vaut que ce que vaut le moteur d'exécution qui l'exécute, et une inadéquation entre ce que vous pensez être déployé et ce qui est réellement déployé est la cause racine de nombreuses pannes déroutantes.

Élément de check-list 1 : Enregistrez les versions du moteur Docker et du plugin Compose.

Exécutez :

docker version --format '{{.Server.Version}}'
docker compose version

Exemple de sortie attendue :

24.0.7
Docker Compose version v2.23.3

Si le moteur est antérieur à 20.10, le support des healthchecks est absent ou se comporte différemment. Certaines fonctionnalités d'orchestration nécessitent également des versions récentes de Compose. Notez ces valeurs dans votre runbook avant d'effectuer tout changement.

Élément de check-list 2 : Énumérez les conteneurs en cours d'exécution et leur état de santé.

Exécutez :

docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

Exemple de sortie attendue :

NAMES       STATUS                    PORTS
api         Up 2 hours (healthy)      0.0.0.0:8080->8080/tcp
worker      Up 2 hours (unhealthy)
redis       Up 2 hours                0.0.0.0:6379->6379/tcp

Remarquez que worker affiche unhealthy tandis que redis n'affiche aucun état de santé car aucun healthcheck n'est défini. C'est votre premier signal de triage : un conteneur non sain est un problème connu, alors qu'un healthcheck manquant est un angle mort.

Élément de check-list 3 : Confirmez où les données sont stockées avant tout remplacement de conteneur.

Un conteneur qui semble sain peut toujours perdre des données s'il écrit dans le système de fichiers du conteneur plutôt que dans un volume monté. Inspectez les montages :

docker inspect api --format '{{ range .Mounts }}{{ .Type }} {{ .Name }} {{ .Source }} -> {{ .Destination }}{{ println }}{{ end }}'

Exemple de sortie attendue :

volume app_data /var/lib/docker/volumes/app_data/_data -> /var/lib/app

Pour les projets Compose, exécutez :

docker compose config

Cela imprime la configuration résolue, y compris les volumes et les définitions de healthcheck. Si vous voyez un montage de type bind comme ./data:/var/lib/app, rappelez-vous qu'il mappe directement un répertoire hôte. Cela fonctionne sur cette machine, mais si le chemin hôte n'existe pas sur une autre machine, le conteneur démarrera avec un répertoire vide ou échouera. Les volumes nommés sont plus portables et plus faciles à sauvegarder.

Élément de check-list 4 : Effectuez un test de redémarrage local avant de modifier la production.

Sur un environnement de staging ou local qui imite la production, exécutez ce qui suit :

docker compose stop api
docker compose up -d api
docker compose ps
docker exec api ls /var/lib/app

Si la liste des fichiers est vide après le redémarrage, le service écrivait dans le système de fichiers du conteneur. Les données de production sont déjà en danger ; corrigez le montage du volume avant toute autre chose.

Responsable et fréquence de revue : Le responsable de plateforme ou d'infrastructure (par exemple, « Alex Chen, responsable infrastructure ») est responsable de la tenue de l'inventaire de l'environnement. Revoyez l'inventaire mensuellement ou à chaque déploiement d'un nouveau service.

Question rapide 1 sur 2

Quelle nouvelle instruction Dockerfile a été introduite pour prendre en charge les healthchecks définis par l'utilisateur ?

La référence [3] indique : « Nouvelle instruction Dockerfile `HEALTHCHECK` pour prendre en charge les healthchecks définis par l'utilisateur ».

Chemin de configuration sûr

La configuration du healthcheck vit dans le Dockerfile ou le fichier Compose. Un healthcheck mal configuré peut amener l'orchestrateur à redémarrer sans fin un conteneur sain, ou à marquer comme sain un conteneur non sain et à continuer de lui envoyer du trafic. Modifiez cette configuration délibérément.

Élément de check-list 1 : Établissez une base de référence de la configuration actuelle du healthcheck.

Lisez les définitions actuelles avant de les modifier :

docker inspect api --format '{{json .Config.Healthcheck}}'

Exemple de sortie attendue :

{"Test":["CMD-SHELL","curl -f http://localhost:8080/health || exit 1"],"Interval":30000000000,"Timeout":5000000000,"Retries":3,"StartPeriod":15000000000}

Notez que Docker stocke les intervalles en nanosecondes. Une erreur courante est d'interpréter 30000000000 comme 30 millisecondes ; c'est en réalité 30 secondes. Vérifiez toujours avec docker inspect plutôt que de supposer à partir du fichier source.

Élément de check-list 2 : Modifiez le healthcheck uniquement dans un fichier contrôlé.

Si vous devez modifier le healthcheck, éditez le Dockerfile ou le fichier Compose, pas le conteneur en cours d'exécution. Par exemple, dans docker-compose.yml :

services:
  api:
    image: myapp:2.4
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8080/ready || exit 1"]
      interval: 10s
      timeout: 3s
      retries: 3
      start_period: 40s

Appliquez ensuite avec :

docker compose up -d --no-deps api

L'option --no-deps évite de redémarrer inutilement les services dépendants, limitant ainsi le rayon d'impact.

Élément de check-list 3 : Vérifiez que le nouveau healthcheck prend effet.

Après l'application, vérifiez l'état au fil du temps :

docker ps --format '{{.Names}}: {{.Status}}'

Séquence attendue :

api: Up 10 seconds (health: starting)
api: Up 45 seconds (healthy)

Si le conteneur bascule entre starting et unhealthy de manière répétée, la période de démarrage est trop courte ou la commande de healthcheck échoue pour des raisons sans rapport avec l'état de préparation. Inspectez les journaux :

docker logs api --tail 50

Recherchez la sortie propre de la commande de healthcheck si elle journalise quelque chose.

Élément de check-list 4 : Testez délibérément la détection de panne.

Une fois qu'un conteneur est sain, simulez une panne pour confirmer que le healthcheck la détecte réellement. Pour un service web, vous pouvez casser temporairement le point de terminaison en déplaçant un fichier :

docker exec api mv /app/health /app/health.disabled

Observez ensuite le changement d'état dans l'intervalle configuré :

docker ps --format '{{.Names}}: {{.Status}}'

Sortie attendue après quelques intervalles :

api: Up 2 minutes (unhealthy)

Cela prouve que l'orchestrateur verra la panne. Restaurez le fichier et confirmez la récupération. Ce test est peu coûteux et devrait faire partie de toute revue de modification du healthcheck.

Responsable et fréquence de revue : Le responsable du service (par exemple, « Priya Shah, responsable ingénierie ») est responsable de la configuration du healthcheck de son service. Revoyez toute modification avant la fusion, et réévaluez les seuils du healthcheck trimestriellement ou après tout changement de code significatif.

Vérification et diagnostic

Un healthcheck est un signal binaire : sain ou non sain. Mais lorsqu'il échoue, vous devez savoir pourquoi. Cette section porte sur la collecte de diagnostics sans altérer le système.

Élément de check-list 1 : Lisez l'historique d'exécution propre de la commande de healthcheck.

Docker ne journalise pas séparément la sortie du healthcheck, mais vous pouvez inspecter les journaux du conteneur pour trouver des indices. Cependant, une meilleure approche consiste à exécuter manuellement la commande de healthcheck à l'intérieur du conteneur :

docker exec api curl -f http://localhost:8080/health

Si cela renvoie un code de sortie non nul, le healthcheck lui-même est précis et le service est effectivement en échec. Si cela renvoie 0 mais que le conteneur est marqué non sain, le problème est probablement un problème de synchronisation (intervalle trop court, délai d'attente trop bas ou période de démarrage insuffisante).

Élément de check-list 2 : Vérifiez l'utilisation des processus et des ressources à l'intérieur du conteneur.

Exécutez :

docker stats --no-stream api

Exemple de sortie attendue :

CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
f1c1a1a1a1a1   api       78.43%    512.3MiB / 1GiB      50.04%    12.3MB / 45.2MB   0B / 0B           23

Une pression élevée sur le CPU ou la mémoire peut entraîner l'expiration des commandes de healthcheck même si l'application fonctionne. Comparez avec les métriques de base d'avant l'incident.

Élément de check-list 3 : Validez les dépendances de la commande de healthcheck.

De nombreux healthchecks reposent sur des outils comme curl, wget ou pg_isready. Si l'image ne les inclut pas, le healthcheck échoue toujours. Exécutez :

docker exec api which curl

Si la commande n'est pas trouvée, vous avez deux options : soit remplacer le healthcheck par une commande utilisant des outils intégrés (par exemple, node -e "require('http').get('http://localhost:8080/health', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))" pour Node.js), soit ajouter l'outil manquant à l'image. La première option est souvent meilleure pour la production car elle évite d'augmenter la taille de l'image pour une seule vérification.

Élément de check-list 4 : Pour les services Compose, passez en revue l'état de santé de toute la pile.

Exécutez :

docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Service}}"

Exemple de sortie attendue :

Name             Status                    Service
myapp_api_1      Up 2 hours (healthy)      api
myapp_worker_1   Up 2 hours (unhealthy)    worker
myapp_redis_1    Up 2 hours                redis

Un worker non sain peut ne pas affecter directement l'API, mais il peut signaler un problème avec une dépendance partagée comme la base de données. Consultez les journaux du worker :

docker compose logs --tail 200 worker

Recherchez des traces de pile, des erreurs de connexion ou des variables d'environnement manquantes.

Responsable et fréquence de revue : L'ingénieur d'astreinte ou l'équipe de fiabilité est responsable de l'exécution des diagnostics pendant un incident. Après résolution, la revue post-incident doit vérifier que les seuils et la commande du healthcheck sont toujours appropriés et qu'aucun nouvel angle mort n'a été introduit.

Modes de défaillance et reprise

Les healthchecks eux-mêmes échouent rarement ; c'est le service derrière eux qui échoue. Mais un healthcheck mal conçu peut créer son propre mode de défaillance : un healthcheck trop strict provoque des redémarrages inutiles, tandis qu'un healthcheck trop laxiste permet à des services cassés de continuer à recevoir du trafic. Voici les modes de défaillance courants et comment les corriger.

Mode de défaillance 1 : Flapping du healthcheck et boucles de redémarrage.

Pourquoi cela arrive : L'intervalle du healthcheck est plus court que le temps de démarrage de l'application, ou le délai d'attente est trop bas pour que la vérification se termine sous charge normale, ou la commande de healthcheck échoue par intermittence en raison de dépendances transitoires.

Comment détecter : L'état du conteneur alterne entre unhealthy et starting de manière répétée. Les journaux montrent des redémarrages fréquents.

Comment récupérer :

  1. Déterminez le temps de démarrage réel en observant le conteneur à partir d'un démarrage propre.
  2. Augmentez start_period à au moins 1,5 fois le temps de démarrage observé.
  3. Si la vérification échoue encore pendant le fonctionnement normal, augmentez timeout ou diminuez interval.
  4. Exemple d'ajustement :
healthcheck:
  test: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]
  interval: 10s
  timeout: 5s
  retries: 5
  start_period: 90s

Mode de défaillance 2 : Conteneurs orphelins marqués sains après la mort du processus.

Pourquoi cela arrive : Si le processus principal meurt mais que le conteneur ne se termine pas (par exemple, un processus zombie ou un PID 1 qui ignore les signaux), le healthcheck peut toujours réussir s'il vérifie un point de terminaison statique. Le service est effectivement en panne, mais Docker le signale comme sain.

Comment détecter : La surveillance externe montre des échecs alors que Docker signale sain. Inspectez le processus principal :

docker inspect api --format '{{.State.Status}} {{.State.Pid}}'

Si le PID est 1 ou un zombie, le processus principal ne tourne pas.

Comment récupérer : Re-concevez le healthcheck pour vérifier la logique applicative réelle, pas seulement un fichier statique. Par exemple, faites en sorte que le point de terminaison de santé effectue une requête triviale en base de données ou vérifie un état critique en mémoire. Alternativement, utilisez un superviseur de processus comme PID 1 (comme tini ou dumb-init) afin que lorsque le processus principal meurt, le conteneur se termine et l'orchestrateur le redémarre.

Mode de défaillance 3 : Le healthcheck réussit mais le service est dégradé.

Pourquoi cela arrive : Le healthcheck teste seulement un point de terminaison simple, mais une dépendance en aval (base de données, cache, API externe) est en panne. Le service peut répondre aux vérifications de santé mais ne peut pas traiter de vraies requêtes.

Comment détecter : Les taux d'erreur augmentent dans les journaux applicatifs, mais l'état de santé reste healthy.

Comment récupérer : Implémentez un healthcheck plus profond qui inclut un test léger de chaque dépendance critique. Par exemple :

curl -f http://localhost:8080/health/deep

Le point de terminaison pourrait renvoyer 200 uniquement si toutes les dépendances sont joignables dans un court délai. Alternativement, utilisez deux healthchecks : un superficiel pour la vivacité (utilisé par l'orchestrateur) et un plus profond pour l'état de préparation (utilisé par un équilibreur de charge) si votre orchestration le prend en charge.

Mode de défaillance 4 : Commande de healthcheck manquante dans l'image.

Pourquoi cela arrive : L'image a été construite sur une base minimale qui n'inclut pas curl, wget ou d'autres outils supposés par le healthcheck. Le healthcheck échoue toujours avec le code de sortie 127 (commande introuvable).

Comment détecter : Le conteneur est immédiatement marqué non sain après le démarrage, et l'inspection des journaux montre quelque chose comme OCI runtime exec failed: exec failed: unable to start container process: exec: "curl": executable file not found in $PATH.

Comment récupérer : Remplacez le healthcheck par une commande qui utilise des outils intégrés au langage ou au système d'exploitation. Pour Python :

healthcheck:
  test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080/health').read()"]

Pour Node.js :

healthcheck:
  test: ["CMD", "node", "-e", "require('http').get('http://localhost:8080/health', r=>process.exit(r.statusCode===200?0:1)).on('error', ()=>process.exit(1))"]

Ces solutions évitent d'ajouter des paquets supplémentaires à l'image.

Responsable et fréquence de revue : Le responsable du service est chargé de corriger le healthcheck en fonction du mode de défaillance. Après récupération, mettez à jour le runbook avec la nouvelle configuration du healthcheck et les leçons apprises. Revoyez l'efficacité du healthcheck trimestriellement.

Question rapide 2 sur 2

Quel est le nombre maximal d'échecs consécutifs autorisés avant que Compose marque un conteneur comme non sain dans l'exemple de la référence [4] ?

La référence [4] montre « retries: 5 » pour le healthcheck de db, ce qui signifie que 5 échecs consécutifs sont autorisés avant que le conteneur soit considéré comme non sain.

Check-list opérationnelle

Voici une check-list opérationnelle condensée quotidienne/hebdomadaire pour les équipes qui exécutent des healthchecks Docker en production. Elle suppose que vous avez terminé les étapes de configuration et de vérification ci-dessus.

Vérifications quotidiennes (ingénieur d'astreinte) :

  • [ ] Exécutez docker ps --format "table {{.Names}}\t{{.Status}}" et confirmez qu'il n'y a pas d'états unhealthy ou starting inattendus.
  • [ ] Pour chaque service avec un healthcheck, confirmez que l'état est stable depuis la dernière heure (utilisez des tableaux de bord de surveillance si disponibles).
  • [ ] Vérifiez les journaux des conteneurs pour les erreurs liées au healthcheck : docker logs <container> --since 1h | grep -i health
  • [ ] Si un conteneur est non sain, suivez les diagnostics de la section Vérification et diagnostic et ouvrez un incident si nécessaire.

Vérifications hebdomadaires (responsable du service) :

  • [ ] Revoyez les configurations des healthchecks par rapport au comportement actuel du service. Portez attention aux nouveaux points de terminaison ou aux délais modifiés.
  • [ ] Exécutez un test d'injection de panne sur un service : cassez intentionnellement le healthcheck et vérifiez que l'orchestrateur marque le conteneur non sain, puis restaurez.
  • [ ] Confirmez que tous les services critiques ont un healthcheck défini. Identifiez tout conteneur sans état de santé et ajoutez-en un si approprié.
  • [ ] Mettez à jour le runbook avec tout changement concernant les commandes, intervalles ou seuils des healthchecks.

Vérifications mensuelles (responsable infrastructure) :

  • [ ] Vérifiez que les versions du moteur Docker et du plugin Compose sont toujours prises en charge et compatibles avec les fonctionnalités de healthcheck.
  • [ ] Auditez l'utilisation des volumes et des montages de type bind pour tous les conteneurs afin d'éviter des pertes de données cachées.
  • [ ] Revoyez les modes de défaillance des healthchecks du mois passé et identifiez des schémas.
  • [ ] Assurez-vous que les commandes de healthcheck ne dépendent pas d'outils qui ne sont pas garantis dans l'image de base.

Responsable et fréquence de revue : Chaque élément de check-list a un responsable nommé comme indiqué. Les vérifications quotidiennes sont la propriété de l'ingénieur d'astreinte, les vérifications hebdomadaires du responsable du service et les vérifications mensuelles du responsable infrastructure. La check-list elle-même est revue et mise à jour après chaque incident majeur ou au moins trimestriellement.

Pièges courants

Même avec une check-list solide, les équipes tombent à plusieurs reprises dans les mêmes pièges. Voici les plus courants et comment les éviter.

Piège 1 : Utiliser les healthchecks pour l'état de préparation au lieu de la vivacité.

Le healthcheck de Docker est un mécanisme de vivacité et de préparation de base, mais ce n'est pas une sonde de préparation complète. Si vous l'utilisez pour conditionner le trafic vers un service qui met longtemps à chauffer, vous risquez soit de router le trafic trop tôt, soit de redémarrer trop souvent. Utilisez start_period pour couvrir le préchauffage initial, et fiez-vous à un équilibreur de charge ou à un maillage de services pour des vérifications de préparation plus nuancées.

Piège 2 : Coder en dur des secrets dans les commandes de healthcheck.

Un healthcheck dans un fichier Compose ou Dockerfile peut nécessiter des identifiants pour appeler un point de terminaison. Évitez d'intégrer directement des secrets ; utilisez des variables d'environnement ou des secrets Docker, et assurez-vous que la valeur n'est pas imprimée dans les journaux. Exemple :

healthcheck:
  test: ["CMD-SHELL", "curl -f -H 'Authorization: Bearer $HEALTH_TOKEN' http://localhost:8080/health || exit 1"]

Définissez HEALTH_TOKEN via l'environnement ou un registre de secrets.

Piège 3 : Ignorer le healthcheck pour les auxiliaires sans état.

Certaines équipes sautent les healthchecks pour les workers sans état ou les sidecars parce qu'ils « ne peuvent pas être non sains ». Mais un worker qui ne peut pas se connecter à la base de données est non sain en pratique. Définissez une vérification simple, par exemple :

healthcheck:
  test: ["CMD-SHELL", "pg_isready -h db -U user -d app || exit 1"]
  interval: 30s
  timeout: 5s
  retries: 3

Piège 4 : Ne pas tester le healthcheck dans la CI.

Le healthcheck est du code, et il peut casser. Incluez une étape dans votre pipeline CI qui construit l'image, démarre le conteneur et vérifie qu'il devient sain. Un simple test de fumée :

docker run -d --name test_health myapp:latest
for i in $(seq 1 30); do
  status=$(docker inspect --format '{{.State.Health.Status}}' test_health)
  if [ "$status" = "healthy" ]; then exit 0; fi
  sleep 2
done
exit 1

Piège 5 : Définir des intervalles trop agressifs.

Un intervalle d'une seconde avec un délai d'attente d'une seconde peut causer plus de mal que de bien. Le healthcheck lui-même consomme du CPU et peut ajouter de la charge au service. Choisissez un intervalle qui a du sens pour votre service : pour une application web typique, 10 à 30 secondes est raisonnable. Moins fréquemment pour les traitements par lots.

Conclusion

Les healthchecks Docker sont une petite partie de votre environnement d'exécution de conteneurs, mais ils constituent la première ligne de défense pour la disponibilité des services. Un healthcheck bien conçu vous dit la vérité sur votre service sans le surcharger, et donne à l'orchestrateur le signal dont il a besoin pour maintenir le trafic vers les instances saines. Un healthcheck mal conçu soit vous ment, soit provoque du churn.

Cet article a parcouru une check-list opérationnelle pratique : commencez par un inventaire de l'environnement pour savoir ce que vous avez, suivez un chemin de configuration sûr pour les modifications, diagnostiquez les problèmes avec des commandes concrètes, comprenez les modes de défaillance courants et comment récupérer, et intégrez les vérifications dans les opérations quotidiennes, hebdomadaires et mensuelles. La section sur les pièges courants devrait vous aider à éviter les erreurs que d'autres ont déjà commises.

La prochaine étape consiste à choisir un service à faible risque et à exécuter les commandes d'inventaire des versions et de l'environnement de cet article. Enregistrez l'état actuel, vérifiez la définition du healthcheck et injectez délibérément une panne pour voir comment votre système réagit. Décidez ensuite si vos seuils et commandes de healthcheck correspondent toujours à la réalité de votre service. Si ce n'est pas le cas, ajustez-les en utilisant le chemin de configuration sûr décrit ici. Rappelez-vous : un healthcheck n'est utile que si vous faites confiance à son signal en cas d'urgence. Construisez cette confiance maintenant, avant d'en avoir besoin.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO