Docker Compose : comprendre les variables ${VAR}, ${VAR:-default}, ${VAR:?error} dans docker-compose.yml

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.

[Découvrir la formation]

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=latest

Docker 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.27nginx:1.27
  • Si TAG absent → 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

SyntaxeSi variable existeSi absente
${VAR}valeurvide
${VAR:-default}valeurdefault
${VAR-default}valeurdefault
${VAR:?error}valeurerreur
${VAR:+x}xvide

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-file sert à Docker Compose.

Astuce

Pour voir la configuration finale après substitutions :

docker compose config

Conclusion

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 -d
docker 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

Romain Drouche
Romain Drouche
Architecte Système | MCSE: Core Infrastructure
Expert en infrastructures IT avec plus de 15 ans d’expérience sur le terrain. Actuellement Chef de projet Systèmes et Réseaux et Référent SSI (Sécurité des Systèmes d’Information), je mets mon expertise au service de la fiabilité et de la sécurité des environnements technologiques.

Laisser un commentaire