Introduction
Les variables d'environnement sont le moyen le plus courant de configurer les services Docker Compose, mais des règles de priorité subtiles, la portée du fichier .env et les différences d'expansion du shell provoquent de fréquentes interruptions. Ce guide explique l'architecture des variables d'environnement Docker Compose, fournit des exemples pratiques pour transmettre des valeurs en toute sécurité et vous donne des commandes de diagnostic pour vérifier la configuration finale avant sa mise en production.
Vous apprendrez :
- Comment Compose résout les variables à partir du shell, du fichier .env, de
environment:, deenv_file:et des valeurs par défaut de l'image, ainsi que l'ordre de priorité exact. - Comment inspecter l'environnement fusionné d'un conteneur en cours d'exécution, déboguer les valeurs manquantes ou incorrectes et tester les modifications sans redéploiement.
- Comment structurer la configuration pour plusieurs environnements, garder les secrets hors du contrôle de code source et éviter les erreurs courantes comme les collisions de noms de variables ou l'utilisation d'un mauvais fichier .env.
- Comment concevoir un plan de reprise et une liste de vérification qui rendent les défaillances visibles avant qu'elles n'affectent les utilisateurs.
Cet article s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui gèrent Docker Compose en développement, préproduction ou production. Nous mettons l'accent sur la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés plutôt que des secrets, vérifier le résultat et documenter comment récupérer lorsque l'état attendu n'est pas atteint.
Inventaire des versions et de l'environnement
Avant de modifier une configuration Compose, établissez une base de référence. Nommez les composants concernés, la plage de versions prise en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande qui vérifie le résultat.
Commencez par ces commandes pour capturer l'état actuel :
docker version --format '{{.Server.Version}}'
docker compose version
Exemples de sortie attendue :
Docker version 24.0.6, build ed223bc
Docker Compose version v2.21.0
Vérifiez que la version de votre fichier Compose est compatible. Depuis Compose v2, la clé de niveau supérieur version: est facultative et ignorée, mais elle peut encore apparaître dans des projets plus anciens. Exécutez :
docker compose config --quiet
Si le fichier est valide, il n'y a pas de sortie et le code de sortie est 0. S'il y a une erreur de syntaxe, Compose imprime un message descriptif et se termine avec un code non nul.
Listez les conteneurs en cours d'exécution et leur état avec :
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
Pour un projet Compose, utilisez :
docker compose ps
Ces commandes montrent quels services sont en cours d'exécution, leur santé et les ports publiés. Elles sont en lecture seule et sûres à exécuter à tout moment.
Consultez les journaux d'un service spécifique avec :
docker compose logs -f app
Cela diffuse les derniers journaux du service app. Recherchez les erreurs liées à l'environnement telles que database connection refused ou missing required variable.
Inspectez l'environnement d'un conteneur en cours d'exécution sans rien modifier :
docker compose exec app printenv
Cela imprime toutes les variables d'environnement visibles à l'intérieur du conteneur, y compris les valeurs définies par Compose, l'image et toute redéfinition au moment de l'exécution. Utilisez-le pour vérifier que les variables sont présentes et ont les valeurs attendues.
Pour les données stockées sur fichier, confirmez où les volumes sont montés avant d'apporter des modifications. Utilisez :
docker inspect -f '{{ json .Mounts }}' app_container
ou pour un service Compose :
docker compose exec app sh -c 'df -h /var/lib/data && ls -la /var/lib/data'
Un volume nommé tel que app_data:/var/lib/data est géré par Docker et est plus facile à réutiliser lors des reconstructions de conteneurs. Un montage de type bind tel que ./data:/var/lib/data mappe un répertoire hôte et est utile pour le développement local, mais peut causer des problèmes de permissions, de portabilité et de sauvegarde si le chemin n'est pas identique sur chaque machine.
Un petit test local de type production doit inclure un test de redémarrage :
docker compose stop app
docker compose up -d app
docker compose exec app printenv DBPASSWORD
Si les données disparaissent ou si la variable change après le redémarrage, le service écrivait probablement dans la couche inscriptible du conteneur ou la variable n'était définie que dans une session shell ponctuelle. Confirmez la persistance avec les commandes ci-dessus avant de vous fier à la configuration.
Chemin de configuration sûr
Les variables d'environnement dans Compose sont résolues à partir de plusieurs sources, et l'ordre de priorité est critique. Compose fusionne les valeurs dans cet ordre, de la priorité la plus basse à la plus haute :
- Environnement par défaut de l'image, le cas échéant (défini par l'instruction
ENVdu Dockerfile). - Valeurs d'un
env_filelisté dans la définition du service (plusieurs fichiers peuvent être listés ; les fichiers ultérieurs remplacent les précédents). - Valeurs de l'environnement shell où vous exécutez
docker compose. - Valeurs d'un fichier
.envdans le répertoire du projet (le même répertoire que le fichier Compose). - Valeurs définies explicitement dans le
environment:du service ouenvironment:avec la syntaxe de mappage.
Dans environment:, les variables définies sans interpolation (par exemple, DBHOST: db) ont toujours la priorité sur celles du shell ou du .env. Si vous utilisez la forme abrégée DBHOST sans valeur, Compose cherche DBHOST dans l'environnement shell ou le fichier .env et utilise cette valeur ; s'il ne la trouve pas, la variable est supprimée ou définie sur une chaîne vide selon la version de Compose (dans la v2, elle est supprimée à moins qu'une valeur par défaut ne soit spécifiée).
Voici un exemple concret de priorité :
Fichier Compose docker-compose.yml :
services:
web:
image: nginx:1.25
env_file:
- common.env
environment:
GREETING: "hello from compose file"
DBHOST: db
ports:
- "8080:80"
common.env :
GREETING=hello from env_file
DBHOST=old_db
DBPORT=5432
Shell avant d'exécuter docker compose up :
export GREETING="hello from shell"
export DBHOST="shell_db"
Fichier .env dans le répertoire du projet :
GREETING=hello from dotenv
DBHOST=dotenv_db
Après docker compose up -d, inspectez le conteneur :
docker compose exec web printenv GREETING
Sortie :
hello from compose file
Parce que GREETING est défini explicitement dans environment:, il gagne. La variable DBHOST est également explicitement définie sur db, donc elle gagne aussi sur le shell et le .env. La variable DBPORT n'est présente que dans common.env, donc elle devient 5432 à l'intérieur du conteneur.
L'utilisation de env_file: est utile pour garder de nombreuses variables dans un fichier séparé, mais sachez qu'elle s'applique à un seul service, pas à l'ensemble du projet. Le fichier .env à la racine du projet est utilisé uniquement pour la substitution de variables dans le fichier Compose, et non automatiquement transmis aux conteneurs.
Pour les secrets comme les mots de passe et les clés API, ne les mettez pas dans le fichier Compose ni dans un env_file ordinaire versionné. Utilisez plutôt les secrets Docker (pour Swarm) ou un fichier .env dédié qui est ignoré par Git. Un motif plus sûr :
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
Définissez ensuite DB_PASSWORD dans votre fichier .env local (non versionné) ou dans votre gestionnaire de secrets CI/CD. Cela garde le secret hors du dépôt et permet des valeurs par environnement.
Pour des tests locaux de type production, utilisez un fichier de surcharge :
docker compose -f docker-compose.yml -f docker-compose.override.yml up -d
Où docker-compose.override.yml contient des surcharges spécifiques à l'environnement. Validez la configuration fusionnée finale avant de l'appliquer :
docker compose config
Cela imprime le fichier Compose entièrement résolu, y compris toutes les substitutions de variables d'environnement et les fichiers fusionnés. Examinez-le attentivement pour détecter les secrets divulgués ou les valeurs incorrectes.
Vérification et diagnostics
Les commandes de cette section vous aident à détecter et diagnostiquer les problèmes de variables d'environnement sans causer de perturbations supplémentaires.
Pour voir l'environnement à l'intérieur d'un conteneur en cours d'exécution, utilisez docker compose exec :
docker compose exec web env
Cela montre toutes les variables d'environnement et leurs valeurs. Filtrez pour une variable spécifique :
docker compose exec web env | grep DBHOST
Inspectez la configuration du conteneur pour voir les variables d'environnement telles qu'enregistrées par Docker :
docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' web_container
Cela est utile lorsque le conteneur a été démarré avec docker run ou via d'anciennes versions de Compose, et que exec n'est pas disponible.
Vérifiez les journaux pour les échecs de démarrage liés à l'environnement :
docker compose logs web | grep -i "error\|fatal\|denied"
Si l'application le permet, essayez de vous connecter aux dépendances depuis l'intérieur du conteneur :
docker compose exec web sh -c 'nc -zv db 5432'
Remplacez nc par telnet ou curl selon l'image. Cela vérifie que le nom d'hôte db se résout et que le port est accessible, ce qui dépend souvent de DBHOST et DBPORT.
Lors du dépannage de la priorité des variables, exécutez docker compose config pour voir le bloc d'environnement exact qui sera transmis au conteneur :
docker compose config | grep -A 10 "environment:"
Cela montre les valeurs résolues, vous aidant à identifier quelle source a fourni une variable. Si une variable est totalement absente, vérifiez qu'elle est définie dans la source attendue et orthographiée correctement (y compris la casse).
Enfin, testez une modification proposée avant de l'appliquer en utilisant docker compose run avec une surcharge temporaire :
docker compose run --rm -e DBHOST=test_db web sh -c 'echo $DBHOST'
Cela exécute un conteneur ponctuel avec l'environnement modifié et imprime la valeur, sans affecter le service en cours d'exécution.
Modes de défaillance et reprise
Même avec une planification minutieuse, des défaillances surviennent. Voici les modes de défaillance courants liés aux variables d'environnement et comment récupérer.
Variable manquante au démarrage du conteneur
Cause : La variable n'est définie dans aucune source, ou le fichier .env est manquant ou mal nommé.
Détection : Le service se termine immédiatement ; les journaux affichent required environment variable ou connection refused.
Reprise :
- Exécutez
docker compose logs <service>pour identifier la variable manquante. - Vérifiez
docker compose configpour voir si la variable apparaît dans le bloc d'environnement. - Ajoutez la variable à la source appropriée (
.env,environment:ou gestionnaire de secrets). - Recréez le service avec
docker compose up -d --force-recreate <service>.
Valeur incorrecte due à la priorité
Cause : La variable est définie à plusieurs endroits, et une source de priorité supérieure écrase la valeur prévue.
Détection : Le conteneur fonctionne mais se comporte de manière inattendue (par exemple, se connecte à une base de données de préproduction en production).
Reprise :
- Exécutez
docker compose exec <service> printenv <VARIABLE>pour voir la valeur réelle. - Exécutez
docker compose configet retracez la variable jusqu'à sa source. - Supprimez ou ajustez la source de priorité inférieure, ou définissez explicitement la variable dans
environment:avec la valeur correcte. - Redémarrez le service.
Secrets accidentellement validés dans le contrôle de version
Cause : Un fichier .env contenant des secrets a été ajouté à Git, ou un secret a été codé en dur dans docker-compose.yml.
Détection : Découvert lors d'une revue de code, d'une analyse de sécurité ou après une fuite de justificatifs.
Reprise :
- Faites pivoter immédiatement le secret divulgué.
- Supprimez le secret du fichier et ajoutez des entrées
.gitignoreappropriées (par exemple,.env,*.env). - Utilisez un outil de gestion des secrets ou les secrets Docker pour les valeurs sensibles.
- Purgez le secret de l'historique Git si nécessaire (par exemple, en utilisant
git filter-repo).
Emplacements de fichiers .env incohérents
Cause : Différents membres de l'équipe ou pipelines CI/CD exécutent docker compose à partir de répertoires différents, donc le fichier .env n'est pas trouvé ou un autre est utilisé.
Détection : Les configurations diffèrent entre les environnements malgré des fichiers Compose identiques.
Reprise :
- Standardisez le placement de
.envdans le même répertoire que le fichier Compose. - Utilisez le drapeau
--env-filepour spécifier un chemin explicite :docker compose --env-file ./config/prod.env up -d. - Documentez les emplacements de fichiers attendus dans le README du projet.
Collision de noms de variables entre les services Compose
Cause : Plusieurs services définissent le même nom de variable avec des valeurs différentes, et en raison des surcharges ou du comportement de fusion, la mauvaise valeur est transmise.
Détection : Un service échoue alors qu'un autre fonctionne, et les journaux montrent que la variable a une valeur inattendue.
Reprise :
- Inspectez chaque service séparément :
docker compose exec <service> printenv <VAR>. - Utilisez des noms de variables uniques par service ou exploitez les profils Compose et les fichiers de surcharge pour segmenter les configurations.
- Mettez à jour les définitions de service et redéployez.
Environnement hôte affectant involontairement Compose
Cause : Le shell où vous exécutez docker compose contient de nombreuses variables exportées, dont certaines sont utilisées par Compose pour la substitution dans le fichier Compose, modifiant ainsi les valeurs de manière inattendue.
Détection : docker compose config montre des valeurs substituées qui diffèrent de ce que vous attendiez.
Reprise :
- Désactivez la variable incriminée dans le shell :
unset <VAR>. - Soyez explicite dans le fichier Compose : utilisez
${VAR:-default}pour fournir une valeur de repli. - Utilisez un shell propre ou un script wrapper qui n'exporte que les variables requises.
Liste de vérification opérationnelle
Utilisez cette liste pour vérifier et maintenir votre configuration de variables d'environnement Docker Compose. Chaque élément comprend la commande ou l'observation, le rôle responsable et la fréquence de révision.
| # | Tâche | Commande / Observation | Rôle responsable | Fréquence de révision |
|---|---|---|---|---|
| 1 | Vérifier les versions de Docker et Compose | docker version && docker compose version | Ingénieur plateforme | Trimestrielle |
| 2 | Valider la syntaxe du fichier Compose et résoudre les variables | docker compose config > /dev/null && echo Valid | Développeur | Avant chaque fusion |
| 3 | Inspecter l'environnement du conteneur en cours d'exécution | docker compose exec <service> printenv | Développeur | À chaque déploiement ou changement de configuration |
| 4 | Vérifier que les secrets ne sont pas dans les journaux ou la sortie de configuration | docker compose config | grep -i 'password\|secret\|key' | Responsable sécurité | Hebdomadaire |
| 5 | Confirmer la persistance des données et de la configuration après redémarrage | docker compose stop && docker compose up -d && docker compose exec ls /data | Ingénieur DevOps | Mensuelle |
| 6 | Examiner le contenu et les permissions d'accès du fichier .env | ls -la .env && cat .env (avec prudence) | Chef d'équipe | Bi-hebdomadaire |
| 7 | Tester la reprise après un scénario de variable manquante | Retirer intentionnellement une variable en préproduction, observer l'échec, puis restaurer et vérifier la correction | Ingénieur QA | Avant chaque mise en production |
| 8 | Auditer les règles de priorité des variables d'environnement avec l'équipe | Revoir la documentation et exécuter un test rapide de priorité | Rédacteur technique / Chef | Annuelle |
Exemple de propriété : Priya Shah, responsable de l'ingénierie, est responsable de la revue finale des changements de variables d'environnement avant le déploiement en production, et elle réexamine les résultats de la liste lors de la revue opérationnelle mensuelle.
Pièges courants et comment les éviter
Voici des nuances supplémentaires qui font trébucher les praticiens.
Utiliser .env pour l'environnement du conteneur
Une erreur répandue consiste à supposer que les variables du fichier .env du projet sont automatiquement transmises à tous les services. Ce n'est pas le cas. Le fichier .env est utilisé uniquement pour l'interpolation dans le fichier Compose. Pour transmettre des variables aux conteneurs, utilisez environment: ou env_file:.
Ne pas mettre entre guillemets les valeurs des variables dans environment:
YAML peut interpréter incorrectement les valeurs contenant des caractères spéciaux (comme :, #, *). Mettez toujours les valeurs entre guillemets, surtout si elles contiennent des espaces ou de la ponctuation.
Mélanger env_file et environment sans comprendre l'ordre de fusion
env_file est appliqué en premier, puis environment écrase. Si vous devez remplacer une seule valeur du fichier, listez-la dans environment:.
Oublier que docker compose up ne recharge pas automatiquement les changements de .env
Si vous modifiez .env ou env_file après que les conteneurs sont en cours d'exécution, vous devez recréer les conteneurs pour que les nouvelles valeurs prennent effet : docker compose up -d --force-recreate.
Utiliser le même nom de variable avec des significations différentes dans différents services
Cela peut causer de la confusion et des surcharges accidentelles. Utilisez un préfixe de service, par exemple WEB_DBHOST vs WORKER_DBHOST.
Dépendre des variables d'environnement de l'hôte dans CI/CD
Les exécuteurs CI peuvent avoir des variables d'environnement définies qui interfèrent. Utilisez --env-file explicite ou définissez toutes les variables nécessaires dans le pipeline, et évitez de dépendre de l'environnement de l'hôte.
Conclusion
Comprendre l'architecture des variables d'environnement Docker Compose est essentiel pour des déploiements fiables. En connaissant l'ordre de priorité, en utilisant des chemins de configuration sûrs et en vérifiant systématiquement avec des commandes comme docker compose config et docker compose exec printenv, vous pouvez prévenir de nombreuses défaillances.
Adoptez les pratiques opérationnelles de ce guide : observez toujours l'état actuel, limitez les changements à une variable à la fois, utilisez des espaces réservés et la gestion des secrets, et ayez un plan de reprise. Incluez la liste de vérification opérationnelle dans la routine de votre équipe pour garder les configurations sécurisées et cohérentes.
Prochaine étape : choisissez un service dans votre projet Compose actuel et effectuez les étapes de l'« Inventaire des versions et de l'environnement ». Comparez l'environnement réel avec ce que vous attendiez et corrigez toute divergence. Documentez ensuite les sources de variables correctes pour votre équipe.
Un flux de travail technique fiable rend les défaillances visibles, protège les valeurs sensibles, limite les changements à la ressource prévue et définit la vérification de la reprise avant qu'un incident ne force la décision.