
Quand on commence à utiliser Docker Compose, on rencontre très vite des expressions comme ${PORT}, ${IMAGE_TAG:-latest} ou encore ${DB_PASSWORD:?Missing password}.
Ces syntaxes permettent de rendre vos fichiers docker-compose.yml dynamiques, réutilisables et plus simples à maintenir. Elles sont particulièrement utiles pour gérer plusieurs environnements : développement, test, production ou homelab.
Dans ce tutoriel, nous allons voir clairement la différence entre les principales formes de variables utilisées dans Docker Compose, avec des exemples concrets et les bonnes pratiques à adopter.
Docker Compose charge automatiquement un fichier .env situé à côté du docker-compose.yml.
🚢 Vous débutez avec Docker ?
Découvrez ma formation Docker pour les débutants : Le Chantier Naval pour apprendre Docker pas à pas, avec une approche simple et concrète.
Sommaire
Variable simple : ${VAR}
C’est la forme la plus basique. Docker Compose remplace la variable par sa valeur si elle existe.
services:
web:
image: nginx:${TAG}TAG=latestDocker utilisera : image: nginx:latest.
Si la variable n’existe pas, elle sera vide : image: nginx:
Peut provoquer une erreur selon le contexte.
Quand l’utiliser ?
- Valeur facultative
- Variable forcément définie ailleurs
- Cas simples
Valeur par défaut : ${VAR:-default}
Cette syntaxe utilise la valeur de la variable si elle existe, sinon elle applique une valeur par défaut.
services:
web:
image: nginx:${TAG:-latest}Résultat :
- Si
TAG=1.27→nginx:1.27 - Si
TAGabsent →nginx:latest
Très utile pour :
- éviter les erreurs
- définir des valeurs standards
- simplifier les déploiements
Variable obligatoire : ${VAR:?message}
Ici Docker Compose stoppe l’exécution si la variable n’est pas définie.
services:
db:
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:?Mot de passe obligatoire}Si DB_PASSWORD est absent, Docker stop le démarrage avec le message : Mot de passe obligatoire.
Idéal pour :
- mots de passe
- tokens API
- secrets critiques
- variables indispensables
Autres syntaxes utiles
${VAR-default} : Utilise la valeur par défaut uniquement si la variable est absente, mais pas si elle est vide.
${VAR:+replacement} : Si la variable existe, remplace par une autre valeur.
${VAR+replacement} : Même logique avec légère différence sur variable vide.
Récapitulatif
| Syntaxe | Si variable existe | Si absente |
|---|---|---|
${VAR} | valeur | vide |
${VAR:-default} | valeur | default |
${VAR-default} | valeur | default |
${VAR:?error} | valeur | erreur |
${VAR:+x} | x | vide |
Bonnes pratiques
Forcer les variables sensibles : ${PASSWORD:?Required}
Prévoir des défauts raisonnables : ${PORT:-8080}
Ne jamais stocker les secrets dans Git : ajoutez .env dans .gitignore.
Erreur fréquente
Beaucoup pensent que ${VAR} suffit partout. En réalité :
- pour un port → prévoir un défaut
- pour un mot de passe → rendre obligatoire
- pour un tag image → fallback conseillé
- Beaucoup pensent que
env_file:remplace${VAR}dans compose,env_file:sert au conteneur,--env-filesert à Docker Compose.
Astuce
Pour voir la configuration finale après substitutions :
docker compose configConclusion
Maîtriser les variables dans docker-compose.yml permet de créer des configurations propres, réutilisables et professionnelles.
Retenez surtout :
${VAR}→ simple remplacement${VAR:-default}→ valeur par défaut${VAR:?error}→ obligatoire
Une fois maîtrisées, ces syntaxes deviennent indispensables pour tous vos projets Docker Compose.
FAQ
Docker Compose lit-il automatiquement le fichier .env ?
Oui, s’il se trouve dans le même dossier que le fichier Compose.
Puis-je utiliser plusieurs fichiers .env ?
Oui, avec --env-file.
docker compose --env-file .env.prod up -ddocker compose --env-file .env --env-file .env.prod up -d
Les variables fonctionnent-elles dans tous les champs YAML ?
Dans la majorité des champs supportés par Docker Compose.
${VAR} et environment: sont-ils identiques ?
Non. ${VAR} remplace une valeur dans le YAML, environment: injecte une variable dans le conteneur.
Pourquoi env_file: ne remplace pas ${VAR} ?
Car Docker Compose lit d’abord le YAML, fait les substitutions, puis seulement ensuite crée le conteneur et injecte env_file.
Ordre logique :
1. Charger variables compose
2. Lire YAML
3. Remplacer ${VAR}
4. Créer conteneur
5. Injecter env_file
