Aller au contenu principal

Comprendre la condition depends_on dans les fichiers Docker compose

Évitez les erreurs de démarrage dans vos applications multi-services. Apprenez à utiliser la propriété healthcheck et la condition depends_on service_healthy de Docker Compose pour que votre application attende que la base de données soit totalement prête avant de démarrer.

· 4 minutes de lecture
Voir la source
Christophe
Amoureux de Markdown, WSL et Docker ~ Curieux insatiable.
Cet article existe aussi en anglais — lire la version originale.

Traduction automatique

Cette traduction a été produite par une IA. Elle peut contenir des contresens ou des maladresses, en particulier sur les termes techniques. En cas de doute, consultez l'article de référence en anglais — c'est lui qui fait foi.

Cet article a plus d'un an, mais il a été relu le 30 juillet 2026 — son contenu est toujours exact.

Comprendre la condition depends_on dans les fichiers Docker compose

⚡
TL;DR

Cet article explique comment empêcher le container d'une application de démarrer avant que sa base de données soit prête, grâce à la propriété healthcheck de Docker Compose (qui définit quand un service est considéré comme prêt) combinée à depends_on: condition: service_healthy sur le service dépendant — de quoi remplacer les fragiles scripts de retry écrits à la main.

Ça ne fait qu'une dizaine de jours que j'ai appris l'astuce, alors qu'elle était bien documentée : gérer le démarrage des services et, surtout, bloquer l'un si l'autre n'est pas prêt (documentation officielle).

Imaginez une application à deux services comme Joomla (voir mon article Créez votre site web Joomla avec Docker), WordPress, LimeSurvey, Laravel et bien, bien d'autres cas d'usage : vous avez une application et cette application a besoin d'une base de données.

Cet article parle d'attendre un service en bonne santé ; Obtenez les informations de santé de vos containers en cours d'exécution parle de lire ce statut de santé depuis la ligne de commande. Et FrankenPHP : un serveur d'applications moderne pour PHP montre exactement le genre de tempête de « Connection refused » que vous obtenez sans ça.

Vous avez, en gros, un fichier compose.yaml comme celui-ci :

services:
joomla:
image: joomla
[...]
joomladb:
image: mysql:8.0.13
[...]

Ce fichier Docker Compose définit deux services : un service Joomla (le système de gestion de contenu) et un service joomladb (la base de données MySQL). Les deux services vont s'exécuter ensemble pour former une application web complète.

Et, oui, ça fonctionne. Vous pouvez exécuter docker compose up --detach, attendre que les deux services soient lancés et, tôt ou tard, votre application sera prête.

Mais vous avez l'intuition que quelque chose ne va pas tout à fait ici... Que se passe-t-il si le service de base de données est lent à démarrer ? Vous auriez l'application (Joomla ici, mais peu importe) qui, dans son processus d'initialisation, va vouloir se connecter à la base de données, et boum ! Ça ne marchera pas et vous recevrez des erreurs Error when connecting to the database. Avec un peu de chance, l'application va réessayer plusieurs fois avant de s'arrêter en erreur. Sans chance, l'application va tout simplement crasher.

Comment résoudre ça ? La réponse tient en deux parties.

  1. Vous devez indiquer à Docker comment il peut savoir que le service est prêt,
  2. Vous devez mettre en pause le service applicatif jusqu'à ce que la base de données soit prête.

La propriété healthcheck​

L'idée est de demander à Docker d'exécuter une commande donnée toutes les xxx secondes jusqu'à obtenir un statut Success (en termes Linux, c'est une commande qui retourne un code de sortie égal à 0).

En cherchant sur Internet avec docker healthcheck suivi du nom d'un service (MySQL, PostgreSQL, Apache, Redis, ...), vous trouverez énormément de possibilités.

Pour MySQL, on utilisera celle-ci :

services:
joomla:
image: joomla
[...]
joomladb:
image: mysql:8.0.13
[...]
// highlight-next-line
healthcheck:
// highlight-next-line
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
// highlight-next-line
timeout: 20s
// highlight-next-line
retries: 10

Ce fichier Docker Compose définit deux services : un conteneur Joomla et une base de données MySQL. Le service joomladb inclut une vérification de santé (healthcheck) qui teste régulièrement si MySQL répond aux requêtes en pingant localhost, avec un délai d'attente de 20 secondes et jusqu'à 10 tentatives avant de considérer le conteneur comme défaillant.

Les quatre lignes ci-dessus demandent à Docker de vérifier la commande définie par la propriété test toutes les 20 secondes, jusqu'à 10 fois. Tant que cette commande ne retourne pas 0, le container est considéré comme unhealthy. Puis, avec un peu de chance, la commande retournera 0 et Docker considérera le service comme healthy.

La propriété depends_on​

La seconde partie consiste maintenant à créer une dépendance dans notre application. Retour au service Joomla (dans notre exemple), on va ajouter une propriété depends_on comme ci-dessous.

services:
joomla:
image: joomla
[...]
// highlight-next-line
depends_on:
// highlight-next-line
joomladb:
// highlight-next-line
condition: service_healthy
joomladb:
image: mysql:8.0.13
[...]
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
timeout: 20s
retries: 10

Ce fichier Docker Compose définit deux services : Joomla et sa base de données MySQL. Le service Joomla dépend du service joomladb et attend que celui-ci soit en bonne santé avant de démarrer, déterminé par une vérification de santé qui teste la connectivité MySQL.

C'est assez explicite, je pense. Docker va mettre en pause la création du container Joomla (juste la création, pas le téléchargement de l'image ni une étape précédente) tant que le service listé dans depends_on n'est pas healthy.

Et vous savez quoi ? Je m'en veux de ne pas avoir découvert ça plus tôt, parce que j'avais déjà mis en place un script comme celui ci-dessous dans mes applications :

Script très simplifié

while [[ ! "$exitCode" = "0" ]]; do
echo "Waiting MySQL to launch on 3306..."
exitCode="$(nc joomladb 3306)"
done

Cet article vous a-t-il été utile ?
Avez-vous suivi les étapes de cet article ?