## Introduction Les variables d'environnement sont le principal moyen de configurer les conteneurs dans Docker Compose sans modifier les images. Elles contrôlent les identifiants de base de données, les indicateurs de fonctionnalités, les points de terminaison d'API et les limites de ressources. Lorsque des variables sont manquantes, mal orthographiées ou exposées, les services échouent au démarrage ou divulguent des secrets dans les journaux. Ce guide décrit les commandes et les modèles nécessaires pour observer, définir, valider et récupérer les variables d'environnement dans les projets Docker Compose. Il s'adresse aux développeurs, aux ingénieurs DevOps et aux équipes de plateforme qui exécutent des applications multi-conteneurs en local et en production. Vous apprendrez à inspecter la version et le projet Compose actuel, à comprendre la précédence et la substitution des variables, à utiliser les fichiers d'environnement en toute sécurité, à transmettre des variables au moment de la construction et de l'exécution, à effectuer des vérifications en lecture seule, à diagnostiquer les échecs courants et à mettre en œuvre une liste de contrôle opérationnelle reproductible. Chaque section comprend des commandes concrètes avec leur sortie attendue, les signes d'échec et les étapes de récupération. ## Inventaire de la version et de l'environnement Avant de modifier une variable, établissez ce que vous exécutez et où se trouve la configuration. Commencez par des observations en lecture seule. Exécutez `docker compose version` pour confirmer la version de l'interface en ligne de commande : ```bash docker compose version ``` La sortie attendue ressemble à : ``` Docker Compose version v2.24.6 ``` Les anciens projets v1 peuvent utiliser `docker-compose` (avec un trait d'union). Si vous voyez `command not found`, vous utilisez soit une ancienne installation, soit le plugin est manquant. Utilisez `docker compose version` pour confirmer la v2. Pour les projets qui doivent prendre en charge la v1, la syntaxe des variables d'environnement est presque identique, mais Compose v2 offre une meilleure interpolation et des profils nommés. Confirmez le nom du projet actif et les fichiers de configuration avec : ```bash docker compose ls ``` Cela répertorie les projets Compose en cours d'exécution, leur statut et les chemins des fichiers de configuration. Si le nom du projet est inattendu, vérifiez la variable `COMPOSE_PROJECT_NAME` ou l'option `-p`. Le nom du projet affecte les noms de réseau, de volume et de conteneur, il est donc important pour le dépannage. Inspectez la configuration résolue sans appliquer de modifications : ```bash docker compose config ``` Cela affiche le YAML entièrement fusionné avec toutes les substitutions de variables appliquées. Il ne démarre pas les conteneurs. Comparez cela à votre `docker-compose.yml` pour voir exactement quelles valeurs seront utilisées. Pour un service spécifique, exécutez `docker compose config `. Si la commande échoue avec `invalid interpolation` ou `required variable is not set`, une variable manquante doit être traitée avant le démarrage de tout conteneur. Listez toutes les variables d'environnement actuellement visibles par un conteneur en cours d'exécution : ```bash docker compose exec env ``` ou, sans entrer dans le conteneur : ```bash docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' ``` Cette sortie comprend les variables provenant de l'image, du fichier Compose, de l'environnement shell et des fichiers d'environnement. Utilisez-la pour vérifier si des secrets sont involontairement exposés. N'imprimez jamais de valeurs sensibles dans les journaux CI ; utilisez `docker inspect` avec un modèle filtré ou une comparaison des fichiers d'environnement à la place. Enregistrez les versions de Docker et Compose, le nom du projet, le chemin du fichier de configuration et un horodatage avant toute modification. Une séquence de commandes d'inventaire simple peut ressembler à : ```bash docker version --format '{{.Server.Version}}' docker compose version docker compose ls docker compose config --quiet date -u +"%Y-%m-%dT%H:%M:%SZ" ``` Enregistrez cette sortie dans un fichier temporaire ou un canal partagé. C'est votre base de référence pour la restauration. ## Chemin de configuration sûr Docker Compose résout les variables d'environnement à partir de plusieurs sources dans un ordre strict. Connaître cet ordre évite les remplacements inattendus. La précédence, de la plus élevée à la plus basse, dans Compose v2 : 1. Variables d'environnement du shell (celles déjà exportées dans la session en cours) 2. Variables du fichier `.env` dans le répertoire du projet (pour `--env-file`, voir ci-dessous) 3. Variables définies dans la section `environment:` du service 4. Variables définies dans une liste `env_file:` (les fichiers ultérieurs remplacent les précédents, et elles sont injectées dans le conteneur mais pas utilisées pour l'interpolation dans le fichier Compose lui-même) 5. Instructions `ENV` du Dockerfile dans l'image Un exemple pratique : Étant donné un `docker-compose.yml` : ```yaml services: web: image: nginx:alpine environment: - API_URL=http://api:8080 - DEBUG=false env_file: - ./common.env ``` Et `common.env` : ``` API_URL=http://localhost:3000 DEBUG=true ``` Si vous exécutez `docker compose config`, vous verrez que `API_URL` prend la valeur `http://api:8080` car `environment:` remplace `env_file:`. Cependant, à l'intérieur du conteneur en cours d'exécution, la variable `DEBUG` sera `true` provenant de `common.env` à moins qu'elle ne soit également dans `environment:`. Cette dualité déroute de nombreux opérateurs : `environment:` est uniquement pour l'interpolation et l'exécution du conteneur, tandis que `env_file:` injecte uniquement des valeurs dans le conteneur ; il ne les rend pas disponibles pour la substitution `${VAR}` dans le fichier Compose. Pour rendre la substitution explicite et éviter les surprises, utilisez un fichier `.env` situé à côté de `docker-compose.yml` (ou référencé via `--env-file`). Le fichier `.env` par défaut est utilisé uniquement pour l'interpolation dans le fichier Compose ; il n'est pas automatiquement injecté dans les conteneurs. Pour que les variables soient disponibles à la fois pour l'interpolation et à l'intérieur du conteneur, vous pouvez soit : - Les définir dans le shell avant d'exécuter `docker compose up` - Les référencer explicitement dans `environment:` en utilisant `${VAR}` - Utiliser plusieurs entrées `env_file:` pour les variables d'exécution et un `.env` séparé pour l'interpolation du fichier Compose Exemple de fichier `.env` pour l'interpolation : ``` POSTGRES_VERSION=16.2 APP_PORT=8080 ``` Et dans `docker-compose.yml` : ```yaml services: db: image: postgres:${POSTGRES_VERSION} ports: - "${APP_PORT}:5432" environment: POSTGRES_PASSWORD: ${DB_PASSWORD} ``` Ici, `DB_PASSWORD` doit également être dans le fichier `.env` ou le shell, sinon `docker compose config` échoue. Si vous devez transmettre des valeurs sensibles, utilisez les secrets Docker ou des magasins de secrets externes, pas des fichiers d'environnement en clair versionnés dans le contrôle de source. Un flux de travail sûr lors de la modification d'une variable d'environnement : 1. Copiez le `docker-compose.yml` et le `.env` actuels vers un emplacement de sauvegarde. 2. Exécutez `docker compose config` pour voir la sortie résolue. Redirigez-la vers un fichier avec `> /tmp/compose-resolved.yml` et inspectez-la pour détecter les remplacements de variables involontaires ou les secrets exposés. 3. Modifiez une variable à la fois. Si plusieurs variables interagissent, documentez la dépendance. Par exemple, changer `DATABASE_URL` peut nécessiter de changer `REDIS_URL` si elles partagent un nom d'hôte. 4. Appliquez la modification avec `docker compose up -d --force-recreate ` uniquement après que `docker compose config` a réussi. 5. Vérifiez avec un contrôle de santé ou une inspection des journaux (voir Vérification et diagnostics). Ne modifiez jamais le fichier `.env` directement sur un serveur de production sans contrôle de version. Utilisez un processus de déploiement contrôlé qui applique la même modification d'abord en préproduction, puis en production, avec un plan de restauration (par exemple, annuler le fichier et exécuter à nouveau `docker compose up -d`). ## Vérification et diagnostics Après avoir modifié les variables d'environnement, vérifiez que le service a bien pris en compte les nouvelles valeurs. Ne supposez pas que `docker compose up -d` sans erreur signifie succès ; un service peut démarrer et être mal configuré. Tout d'abord, vérifiez l'état du conteneur : ```bash docker compose ps ``` Sortie saine attendue : ``` NAME COMMAND SERVICE STATUS PORTS myapp-web-1 "nginx -g 'daemon of…" web running (healthy) 0.0.0.0:8080->80/tcp ``` Si l'état est `restarting`, `unhealthy` ou `exited`, inspectez immédiatement les journaux : ```bash docker compose logs --tail=50 ``` Pour une variable d'environnement mal configurée, les messages de journal typiques comprennent : - `panic: runtime error: invalid memory address or nil pointer dereference` (courant dans les applications Go lorsqu'une variable d'environnement requise est vide) - `Error: connect ECONNREFUSED 127.0.0.1:5432` (hôte ou port de base de données incorrect à partir de `DATABASE_URL`) - `The server requested authentication method unknown to the client` (incompatibilité de variable d'authentification Postgres) - `Error: Missing required environment variable: API_KEY` Utilisez `docker compose exec` pour inspecter la valeur de variable en direct à l'intérieur du conteneur : ```bash docker compose exec web printenv DEBUG ``` Si le conteneur redémarre trop rapidement, utilisez `docker inspect` sur l'ID du conteneur : ```bash docker inspect --format '{{.State.Status}} {{.State.ExitCode}}' ``` Pour les conteneurs PostgreSQL, vous pouvez également vérifier le mot de passe configuré en vous connectant : ```bash docker compose exec db psql -U postgres -c "SELECT current_user, current_database();" ``` Si l'authentification échoue, la variable `POSTGRES_PASSWORD` n'a probablement pas atteint le conteneur. Vérifiez à nouveau la sortie de `docker compose config`. Pour diagnostiquer les problèmes de précédence des variables, comparez la configuration résolue à l'environnement réel du conteneur : ```bash # Environnement Compose résolu pour le service web : docker compose config web | grep -A5 "environment" # Environnement réel du conteneur : docker inspect $(docker compose ps -q web) --format '{{range .Config.Env}}{{println .}}{{end}}' ``` Toute incohérence indique un remplacement par `env_file`, le shell ou les valeurs par défaut de l'image. Exécutez un test de redémarrage pour confirmer la persistance de la configuration pilotée par l'environnement. Pour un service avec état comme une base de données, arrêtez et recréez le conteneur, puis vérifiez que les données et la configuration restent : ```bash docker compose stop db docker compose rm -f db docker compose up -d db # Après le démarrage, vérifiez une variable connue : docker compose exec db printenv POSTGRES_DB ``` Si la variable est vide ou si la base de données ne démarre pas, la variable n'a pas été définie dans le fichier Compose mais peut-être dans une session shell précédente ou dans la valeur par défaut de l'image. C'est un échec courant lors du passage du local à l'intégration continue. ## Modes d'échec et récupération Plusieurs erreurs courantes causent des problèmes de variables d'environnement dans Docker Compose. Comprendre pourquoi elles se produisent et comment les récupérer permet de gagner du temps et d'éviter des incidents de production. ### 1. L'interpolation de variable échoue lors de `docker compose up` **Symptôme :** ``` ERROR: The interpolation of '${DB_PASSWORD}' in 'services.db.environment.POSTGRES_PASSWORD' is not valid. Required variable DB_PASSWORD is missing. ``` **Pourquoi :** Vous avez référencé `${DB_PASSWORD}` dans le fichier Compose, mais il n'est pas défini dans l'environnement shell ni dans le fichier `.env`. Compose v2 ne lit que le fichier `.env` dans le répertoire du projet (ou spécifié par `--env-file`), pas les entrées `env_file:`. **Récupération :** - Ajoutez la variable à `.env` dans le même répertoire que `docker-compose.yml`. - Ou exportez-la dans le shell avant d'exécuter Compose : `export DB_PASSWORD=yourpassword`. - Ou passez-la explicitement : `docker compose --env-file ./config/secrets.env up -d`. - Évitez de versionner des secrets dans `.env` ; utilisez un gestionnaire de secrets CI et écrivez le fichier lors du déploiement. ### 2. Les variables de `env_file` ne sont pas utilisées pour la substitution **Symptôme :** Vous définissez `DATABASE_URL=postgres://user:pass@db:5432/mydb` dans `env_file`, mais le fichier Compose affiche toujours `${DATABASE_URL}` non résolu dans `cmd` ou `entrypoint`. **Pourquoi :** `env_file` injecte des variables dans le conteneur au moment de l'exécution ; il n'est pas disponible pour l'analyseur du fichier Compose. L'analyseur n'utilise que les variables d'environnement du shell et le fichier `.env`. **Récupération :** Déplacez la variable vers le fichier `.env` si vous en avez besoin pour l'interpolation, ou référencez-la directement dans la commande avec une valeur codée en dur. N'oubliez pas que les variables `.env` ne sont pas automatiquement injectées dans les conteneurs ; vous devez également les lister sous `environment:` ou `env_file:` si l'application en a besoin. ### 3. Fuite de variables sensibles via `docker inspect` ou `docker compose config` **Symptôme :** L'exécution de `docker inspect` affiche des mots de passe, des jetons ou des clés API dans la liste d'environnement. Ces valeurs peuvent se retrouver dans les journaux CI, les bundles de support ou les tableaux de bord de surveillance. **Pourquoi :** Transmettre des secrets via `environment:` ou `env_file:` les rend visibles à toute personne ayant accès à l'API Docker sur l'hôte. Ils sont également stockés dans les métadonnées du conteneur. **Récupération :** - Utilisez les secrets Docker si vous êtes en mode Swarm, ou des fichiers de secrets montés par liaison pour les projets Compose. Par exemple : ```yaml services: web: secrets: - db_password secrets: db_password: file: ./secrets/db_password.txt ``` - Au minimum, utilisez un gestionnaire de secrets externe et injectez les secrets via le point d'entrée du conteneur à partir d'un fichier monté. - Évitez d'imprimer la sortie `env` dans la CI. Utilisez `docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' | grep -v 'PASSWORD\|TOKEN\|KEY'` pour filtrer les clés sensibles, mais ne faites jamais confiance aux filtres seuls ; la valeur peut apparaître dans les lignes de commande ou les contrôles de santé. ### 4. L'environnement hôte remplace `.env` de manière inattendue **Symptôme :** Dans la CI ou sur la machine d'un développeur, le même fichier Compose résout une variable différemment que sur une autre machine. `docker compose config` affiche une valeur différente de celle du `.env`. **Pourquoi :** Les variables d'environnement du shell ont une précédence plus élevée que les variables du fichier `.env`. Si un développeur a `DEBUG=true` exporté dans son shell, cela remplace `DEBUG=false` dans `.env`. Cela conduit à un comportement incohérent entre les environnements. **Récupération :** - Exécutez `docker compose config` localement et dans l'environnement pour comparer. Si vous avez besoin d'une construction déterministe, désactivez les variables en conflit ou utilisez `env -i docker compose config` pour voir la base de référence. - Documentez quelles variables peuvent être remplacées par le shell et lesquelles doivent provenir de `.env` ou des secrets CI. - Envisagez d'utiliser un répertoire de projet dédié sans variables shell héritées. ### 5. Les modifications de `.env` ne sont pas prises en compte après `docker compose up` **Symptôme :** Vous modifiez `.env`, exécutez `docker compose up -d`, mais les conteneurs en cours d'exécution utilisent toujours les anciennes valeurs. **Pourquoi :** Les variables d'environnement sont fixées à la création du conteneur. Mettre à jour `.env` seul ne recrée pas les conteneurs existants. `docker compose up -d` ne recrée que les conteneurs avec une image ou une configuration de service modifiée ; il peut ne pas détecter un changement dans l'environnement résolu si le fichier Compose lui-même n'a pas changé. **Récupération :** - Forcer la recréation du service affecté : `docker compose up -d --force-recreate `. - Ou arrêtez et supprimez les conteneurs, puis redémarrez : `docker compose down && docker compose up -d`. - Avant de forcer la recréation, exécutez `docker compose config` pour confirmer les nouvelles valeurs résolues. ### 6. Utilisation incorrecte des modificateurs `:ro` ou `:rw` dans les chemins `env_file` **Symptôme :** Compose ne parvient pas à analyser une entrée `env_file` comme `./env/common.env:ro`. **Pourquoi :** `env_file` ne prend pas en charge les modificateurs de montage ; cette syntaxe est uniquement pour les volumes. C'est une erreur courante de copier-coller. **Récupération :** Supprimez le modificateur : `- ./env/common.env`. Si vous avez besoin que le fichier soit en lecture seule à l'intérieur du conteneur, placez-le dans un montage lié et sourcez-le via `env_file` en utilisant le chemin du conteneur. ## Liste de contrôle opérationnelle Utilisez cette liste de contrôle avant et après toute modification des variables d'environnement Docker Compose. Elle suppose d'abord un environnement de préproduction similaire à la production, puis la production. Chaque élément a un responsable et une fréquence de révision. **Avant la modification (responsable : ingénieur DevOps ou propriétaire du service ; révision : à chaque déploiement)** - [ ] Enregistrez la sortie actuelle de `docker compose version` et `docker compose config` dans un fichier journal daté. - [ ] Identifiez tous les services affectés par la modification de variable à l'aide de `docker compose config --services`. - [ ] Confirmez que la variable n'est pas codée en dur dans l'image ou remplacée par une source de précédence plus élevée. - [ ] Vérifiez l'utilisation de `${VAR}` dans les sections `command:`, `entrypoint:`, `healthcheck:` ou `environment:`. - [ ] Assurez-vous que les secrets ne sont pas actuellement dans `.env` ou `env_file` versionné dans le contrôle de source. - [ ] Définissez la valeur attendue et une commande de validation pour chaque variable (par exemple, `docker compose exec web env | grep API_URL` doit renvoyer `http://api:8080`). - [ ] Sauvegardez le fichier Compose actuel et `.env` dans un emplacement versionné (par exemple, une étiquette Git ou un magasin d'artefacts). **Après la modification (responsable : même ingénieur ; vérifier dans les 30 minutes suivant le déploiement)** - [ ] Exécutez `docker compose config` et comparez avec la sortie attendue. - [ ] Démarrez ou recréez le service avec `docker compose up -d --force-recreate `. - [ ] Vérifiez l'état du service avec `docker compose ps` (recherchez `running (healthy)`). - [ ] Inspectez les journaux pour détecter les erreurs liées aux variables manquantes ou invalides. - [ ] Exécutez la commande de validation pour la variable modifiée. - [ ] Effectuez un test de redémarrage : `docker compose stop && docker compose start ` et revalidez. - [ ] Confirmez qu'aucune valeur sensible n'apparaît dans la sortie de `docker inspect` ou les journaux. - [ ] Mettez à jour les manuels d'exploitation ou la documentation avec la nouvelle variable et sa source de vérité. **Plan de restauration (responsable : ingénieur d'astreinte ; à exécuter si les vérifications post-modification échouent)** - [ ] Annulez les modifications du fichier `.env` et Compose à partir du contrôle de version. - [ ] Exécutez `docker compose up -d --force-recreate` avec la configuration précédente. - [ ] Vérifiez que les valeurs de variable précédentes connues comme bonnes sont restaurées. - [ ] Informez l'équipe et enregistrez le calendrier de l'incident. Cette liste de contrôle ne remplace pas les tests CI. Ajoutez une étape de pipeline qui exécute `docker compose config --quiet` et un test de fumée qui vérifie qu'un service peut récupérer une variable connue. Par exemple, un conteneur Nginx peut exposer un en-tête avec `add_header X-App-Env $APP_ENV;`, et le test vérifie que l'en-tête est égal à `staging` ou `production`. ## Pièges courants et comment les éviter Les pièges suivants apparaissent de manière répétée dans les projets Compose du monde réel. Chacun comprend un exemple concret et une mesure préventive. ### Piège 1 : Supposer que les variables `env_file` sont disponibles pour l'interpolation Compose Comme indiqué, `env_file` est uniquement pour l'exécution. Les développeurs écrivent souvent : ```yaml services: app: image: myapp env_file: - ./app.env environment: - LOG_LEVEL=${LOG_LEVEL} ``` Ils s'attendent à ce que `${LOG_LEVEL}` soit résolu à partir de `app.env`. Ce n'est pas le cas. La bonne approche est de mettre `LOG_LEVEL` dans `.env` ou de l'exporter dans le shell, et éventuellement de le lister également dans `env_file` si l'application en a besoin à l'intérieur du conteneur. Un modèle plus sûr est d'éviter `env_file` pour les variables utilisées dans le fichier Compose ; utilisez `.env` pour l'interpolation et `environment:` pour les valeurs d'exécution explicites. ### Piège 2 : Mélanger les fichiers `.env` de développement et de production Utiliser un seul `.env` pour tous les environnements entraîne des fuites de secrets dans les conteneurs de développement ou des valeurs de production dans les tests locaux. Utilisez plutôt des fichiers spécifiques à l'environnement : ``` .env.staging .env.production ``` Déployez avec `docker compose --env-file .env.production up -d`. Conservez ces fichiers dans un magasin sécurisé, pas dans le référentiel Git. ### Piège 3 : Remplacer une variable dans `environment:` mais oublier la dépendance dans un autre service Supposons que les services `web` et `worker` aient tous deux besoin de `API_URL`. Vous modifiez `API_URL` uniquement pour `web`. Le worker conserve silencieusement l'ancienne URL, provoquant un comportement incohérent. Pour éviter cela, définissez des variables partagées dans un `.env` commun et référencez-les dans les deux services, ou utilisez des ancres YAML et une source unique de vérité. Exécutez `docker compose config` et recherchez le nom de la variable pour voir toutes les occurrences : ```bash docker compose config | grep -n "API_URL" ``` ### Piège 4 : Ne pas mettre entre guillemets les valeurs de variable avec des caractères spéciaux L'analyse YAML peut mal interpréter les valeurs contenant `:`, `#`, `-` ou des espaces. Par exemple : ```yaml environment: - GREETING=Hello, World! # échoue car la virgule et l'espace sont acceptables ? En fait la virgule est acceptable, mais le `!` peut causer des problèmes dans certains analyseurs YAML. Mieux vaut mettre entre guillemets : - GREETING="Hello, World!" - DSN=postgres://user:pass@db:5432/mydb?sslmode=disable # le deux-points peut causer des problèmes ? En fait le deux-points est acceptable s'il n'y a pas d'espace après. Mais `#` pourrait commenter le reste. ``` Mettez toujours entre guillemets les valeurs contenant des caractères spéciaux, y compris `*`, `?`, `[`, `]`, `{`, `}`, `#`, `&`, `!`, `|`, `>`, `%`, `@` et les accents graves. Utilisez des guillemets simples pour une interprétation littérale et des guillemets doubles lorsque vous devez inclure une interpolation. Exemple : ```yaml environment: - "PASSWORD=pa$$w0rd" # les guillemets doubles empêchent $ d'interpoler - 'REGEX=[0-9]+' ``` ### Piège 5 : S'appuyer sur les valeurs par défaut sans vérifier Compose autorise les valeurs par défaut avec `${VAR:-default}`. Cela peut masquer les fautes de frappe. Si vous vous attendez à ce que `POSTGRES_USER` soit `admin` mais que le `.env` contient `POSTGRES_USR=admin` (faute de frappe), la variable se résout par défaut `postgres`, ce qui peut fonctionner mais avec le mauvais utilisateur. Évitez les valeurs par défaut pour les variables critiques, ou ajoutez une étape de validation : ```yaml environment: - POSTGRES_USER=${POSTGRES_USER:?POSTGRES_USER is required} ``` La syntaxe `:?` force une erreur si la variable est vide, rendant les erreurs visibles. ### Piège 6 : Stocker des secrets dans `docker-compose.override.yml` et le versionner Le fichier de remplacement est pratique pour les remplacements locaux mais contient souvent des secrets comme les mots de passe de base de données. S'il est versionné dans le contrôle de source, les secrets fuient. Utilisez un `.gitignore` pour les fichiers de remplacement contenant des secrets, ou mieux, ne mettez jamais de secrets dans les fichiers Compose ; utilisez les secrets Docker (Swarm) ou des fichiers montés par liaison depuis un emplacement sécurisé. ## Conclusion Les variables d'environnement sont le plan de contrôle des applications conteneurisées. Dans Docker Compose, les gérer correctement nécessite de comprendre l'ordre de résolution, de séparer la configuration au moment de la construction de celle au moment de l'exécution, et de vérifier les modifications avec des commandes observables. Les commandes de cet article fournissent un flux de travail reproductible : inventorier l'état actuel, apporter une modification ciblée, valider la configuration résolue, observer le conteneur en cours d'exécution et disposer d'un chemin de restauration. Commencez par une modification de variable à faible risque dans un environnement hors production. Exécutez `docker compose config` pour voir l'effet, recréez le service et confirmez que le conteneur voit la valeur attendue à l'aide de `docker compose exec`. Au fur et à mesure que vous gagnez en confiance, étendez la liste de contrôle à toute la configuration pilotée par l'environnement. Le principe fondamental est la sécurité opérationnelle : n'injectez jamais de secrets à partir de fichiers non chiffrés, ne modifiez jamais plusieurs variables interdépendantes à la fois et vérifiez toujours avec une commande concrète que le conteneur en cours d'exécution correspond à la configuration déclarée. Avec ces pratiques, les variables d'environnement deviennent un mécanisme de configuration fiable, vérifiable et réversible.