2.4 · Configuration : ENV, ARG et fichiers .env

Niveau 2 · Dockerfile & build

2.4Configuration : ENV, ARG et fichiers .env

Objectif : Rendre une image configurable sans la reconstruire, du dev à la prod.
Temps estimé : 11 min · lecture autonome · Si vous n'avez que 5 min : lisez « L'essentiel en 30s » + le schéma.

L'essentiel en 30 secondes

  • ARG construit, ENV exécute : ARG vit pendant le build puis disparaît, ENV persiste dans le conteneur — ne pas les confondre.
  • Défauts sains + surcharge : l'image tourne sans rien et chaque environnement surcharge au run — une image, N environnements.
  • Secrets hors image : structure versionnée (.env.example), valeurs sensibles hors git — jamais de mot de passe committé.

Mini-cas filé — Idir et les deux ports d'une même image

L'image versionnée d'Idir (2.3) tourne, mais le dev écoute sur 3000 et la recette sur 8080 : l'équipe rebuildait une image par environnement. Idir déclare ENV PORT=3000 par défaut dans le Dockerfile : l'image tourne sans rien. Puis il surcharge au lancement (-e PORT=8080) : deux conteneurs de la même image 1.0 répondent chacun sur leur port. La clé de build (ARG) reste cantonnée au build. En 2.5, Idir vérifiera qu'aucune variable sensible n'est restée figée dans l'image.

Suite du fil rouge 2.3 : la même image d'Idir sert tous les environnements — et continue en 2.5.

1. ENV vs ARG : deux moments

ARG sert pendant le build (version à compiler, passée par --build-arg), puis disparaît : introuvable au run. ENV persiste dans le conteneur vivant (port, mode, URL de base) et reste surchargeable au run -e. Règle : ARG construit, ENV exécute. Idir passe sa version de build en ARG et son port d'écoute en ENV.

2. Les valeurs par défaut qui aident

On déclare des défauts sains dans le Dockerfile (ENV PORT=3000 NODE_ENV=production) : l'image tourne sans rien. Chaque environnement surcharge au lancement (-e PORT=8080). Une image qui exige dix variables obscures sans défauts est une image mal conçue : noms explicites, documentés, défauts qui tournent. Idir lance deux conteneurs de la même image avec deux PORT : chacun répond sur le sien.

3. Le .env : la config versionnée sans secrets

En Compose (niveau 3), un fichier .env centralise les variables par environnement. Principe : la structure est versionnée (.env.example avec noms et défauts non sensibles), les valeurs sensibles restent hors git (fichier local non commité, gestionnaire de secrets, variables CI). Jamais de mot de passe commité, jamais de secret figé en ENV dans l'image : visible dans l'historique. Idir versionne l'exemple et garde les valeurs sensibles hors dépôt.

Erreur d'interprétation fréquente : « Je mets le mot de passe en ENV dans le Dockerfile, c'est de la configuration ». Non : un ENV figé au build reste lisible dans l'historique et part au push — ce n'est plus de la config, c'est une fuite. La règle d'Idir : réglages simples en ENV avec défauts sains, secrets injectés au run (ou via secrets managés), jamais committés.
Une image, N environnements Défauts sains dans l'image, surcharge au lancement ENV par défaut L'imagetourne sans rienrun -e surcharge Chaque envajuste au lancement.env par environnement Structureversionnée, secrets hors git
Défauts sains dans l'image, surcharge au lancement
Version texte du schéma (SEO / lecteurs d'écran / traduction) : 1) Idir DÉCLARE : ENV PORT=3000 par défaut dans le Dockerfile — l'image tourne sans surcharge ; ARG réservé aux valeurs de build. 2) Il SURCHARGE : -e PORT=8080 au run pour la recette, sans reconstruire — même image 1.0, deux ports. 3) Il RANGE : structure en .env.example versionné, valeurs sensibles hors git (fichier local, secrets managés). Leçon : la config voyage hors de l'image, les secrets ne la touchent jamais.

🔎 Exemple concret — 🔎 Exemple concret — Même image, deux ports

L'image d'Idir, configurable sans reconstruction :

# Dockerfile
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENV PORT=3000 NODE_ENV=production
EXPOSE 3000
CMD ["sh", "-c", "node server.js --port $PORT"]

docker run -d -p 3000:3000 mon-app:1.0
docker run -d -p 8080:8080 -e PORT=8080 mon-app:1.0

Lecture : la même image 1.0 sert deux environnements : défaut 3000, surcharge 8080 au lancement.

Leçon : la config voyage hors de l'image — on ne rebuild pas pour changer un port.

Vocabulaire de la section

ARG
Une variable de BUILD, disponible pendant docker build uniquement (via --build-arg), absente au run.

Exemple simple : Idir passe la version à compiler en ARG au build.

Ce que ce n'est pas : une variable d'exécution persistée.

Réflexe : valeur de build = ARG.

ENV
Une variable d'EXÉCUTION, persistée dans le conteneur vivant, avec défaut sain surchargeable au run.

Exemple simple : Idir déclare ENV PORT=3000, surchargé en 8080 au run.

Ce que ce n'est pas : une variable qui disparaît après le build.

Réflexe : réglage du vivant = ENV.

-e
La surcharge d'une variable au docker run : l'environnement ajuste sans reconstruire l'image.

Exemple simple : Idir lance la recette avec -e PORT=8080 sur la même image.

Ce que ce n'est pas : une recompilation pour changer un réglage.

Réflexe : ajuster = -e au lancement.

Défaut sain
Une valeur ENV qui fait tourner l'image sans aucune surcharge ; base d'une image bien conçue.

Exemple simple : L'image d'Idir démarre en 3000 sans aucune option.

Ce que ce n'est pas : dix variables obscures exigées sans défauts.

Réflexe : tourne sans rien d'abord.

En pratique — En pratique — Configurable en 10 minutes

  1. Ajoutez ENV PORT=3000 à votre Dockerfile et rebuildez.
  2. Lancez deux conteneurs de la même image avec deux PORT différents (-e).
  3. Vérifiez que chacun répond sur son port.
  4. Listez les variables vues de l'intérieur (exec + env).
Une seule image sert tous vos environnements par simple surcharge.

Script prêt à dire — vendre la config sans rebuild (30 s)

« Une seule image 1.0 pour tous les environnements : par défaut elle écoute sur 3000, la recette surcharge en 8080 au lancement, sans reconstruire. Les réglages simples voyagent en ENV, la clé de build reste en ARG, et les secrets ne sont jamais dans l'image. Même version partout, juste la config qui change. »

À dire en lançant les deux conteneurs d'Idir côte à côte, même image, deux ports.

Modèle copier-coller — Dockerfile configurable (ARG + ENV)

FROM node:20-slim
ARG APP_VERSION=1.0
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENV PORT=3000 NODE_ENV=production APP_VERSION=${APP_VERSION}
EXPOSE 3000
CMD ["sh", "-c", "node server.js --port $PORT"]

ARG disparu

Une version lue au run mais passée en ARG : vide au démarrage — Idir la recopie en ENV si le vivant en a besoin.

Dix variables obscures

Image qui exige dix -e sans défauts : Idir ajoute des défauts sains et documente chaque nom.

Secret en ENV figé

Mot de passe en ENV dans le Dockerfile, visible dans history : Idir le retire et l'injecte au run.

.env commité

Fichier .env avec valeurs sensibles poussé sur git : Idir versionne .env.example et garde les valeurs hors dépôt.

✓ Bonnes pratiques

  • Des défauts qui tournent sans rien.
  • Noms de variables explicites et documentés.
  • Secrets hors git, toujours.

✗ Pièges fréquents

  • Mettre un secret en ENV committé (visible dans history).
  • Confondre ARG et ENV (disparu au run).
  • Exiger dix variables obscures sans défauts.

Points clés à retenir

  • ARG = build (disparaît), ENV = run (persiste et se surcharge).
  • Défauts sains, surcharge au lancement (-e).
  • Une image, N environnements : on ne rebuild pas pour un réglage.
  • Secrets hors image et hors git (structure versionnée, valeurs protégées).

Défi 48h — appliquez demain

Rendez votre image 1.0 configurable : ENV PORT par défaut, deux conteneurs deux ports (-e), contrôle exec + env à l'intérieur, et .env.example sans aucune valeur sensible.

Checklist sortie de section
  • Je peux distinguer ARG (build) et ENV (run) et les placer correctement.
  • Je sais servir N environnements avec une seule image (défauts + -e).
  • Je garde structure versionnée et secrets hors git et hors image.
Auto-évaluation 1-5 : est-ce que mon image tourne sans surcharge ?est-ce qu'aucun secret ne dort dans mon Dockerfile ou mon historique ?

Questions fréquentes

Où mettre un mot de passe de base ?

Ni dans le Dockerfile ni dans l'image : en variable au run (-e), en .env local non commité, ou en secret managé (secrets Compose, variables CI, orchestrateur). Un secret figé en ENV reste lisible dans l'historique et part au push.

ENV ou fichier de config monté ?

ENV pour les réglages simples (ports, modes, URL) ; fichier monté pour les configs riches (nginx.conf, certificats). Les deux se combinent : l'un n'exclut pas l'autre.

Vérifiez votre compréhension

Vous changez le port d'écoute entre dev et prod. Que faites-vous ?

Ressources supplémentaires (optionnel, pour aller plus loin)

Examen du niveau 2Questions inédites et durcies pour valider vos acquis