DevToolBoxGRATUIT
Blog

Guide .env : Bonnes pratiques des variables d'environnement

10 min de lecturepar DevToolBox

Les variables d'environnement gardent les secrets hors du code source et permettent de modifier la configuration sans redéployer. Le fichier .env est devenu la méthode standard pour les gérer localement. Ce guide couvre les règles de syntaxe, la configuration des frameworks, la sécurité, les fichiers spécifiques à l'environnement, l'intégration Docker, les erreurs courantes et les alternatives en production.

Règles de syntaxe .env

Un fichier .env est un fichier texte brut avec une variable par ligne. Voici les règles que tout développeur doit connaître :

Syntaxe de base

Chaque ligne suit le modèle KEY=VALUE. Pas d'espaces autour du signe égal.

# .env
DATABASE_URL=postgres://localhost:5432/mydb
API_KEY=sk-1234567890abcdef
PORT=3000
DEBUG=true

Règles de guillemets

Les valeurs peuvent être sans guillemets, entre guillemets simples ou doubles. Le comportement diffère :

# Unquoted — trailing whitespace trimmed
APP_NAME=My Application

# Single quotes — literal, no interpolation
PASSWORD='p@$$w0rd#123'

# Double quotes — escape sequences + interpolation
GREETING="Hello\nWorld"
FULL_URL="${BASE_URL}/api/v1"
  • Sans guillemets : les espaces en fin de ligne sont supprimés, pas de séquences d'échappement.
  • Guillemets simples : la valeur est prise littéralement, pas d'interpolation ni d'échappement.
  • Guillemets doubles : supporte les séquences d'échappement (\n, \t) et l'interpolation de variables.

Valeurs multilignes

Utilisez des guillemets doubles et \n pour les sauts de ligne, ou des sauts de ligne réels entre guillemets doubles :

# Method 1: \n in double quotes
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIB...\n-----END RSA PRIVATE KEY-----"

# Method 2: actual newlines in double quotes
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY-----"

Commentaires

Les lignes commençant par # sont des commentaires. Les commentaires en ligne fonctionnent uniquement avec les valeurs sans guillemets dans certains parseurs :

# This is a full-line comment
DATABASE_URL=postgres://localhost/mydb  # inline comment (some parsers)

# Empty lines are ignored

API_KEY=abc123  # This may or may not work depending on the parser

Interpolation de variables

Référencez d'autres variables avec la syntaxe ${VAR} (supporté par la plupart des parseurs dans les valeurs entre guillemets doubles) :

BASE_URL=https://api.example.com
API_V1=${BASE_URL}/v1
API_V2=${BASE_URL}/v2

DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
DATABASE_URL=postgres://${DB_HOST}:${DB_PORT}/${DB_NAME}

Configuration des frameworks

Node.js (dotenv)

Le chargeur .env le plus populaire pour Node.js. Installation et configuration :

# Install
npm install dotenv

# --- app.js (CommonJS) ---
require('dotenv').config();
console.log(process.env.DATABASE_URL);

# --- app.ts (ES Modules) ---
import 'dotenv/config';
console.log(process.env.DATABASE_URL);

# --- Or load from CLI ---
node -r dotenv/config app.js
node -r dotenv/config app.js dotenv_config_path=.env.local

Next.js, Vite et Create React App chargent automatiquement les fichiers .env — aucun package nécessaire.

Python (python-dotenv)

Charger .env dans les projets Python :

# Install
pip install python-dotenv

# --- app.py ---
from dotenv import load_dotenv
import os

load_dotenv()  # loads .env from current directory
# load_dotenv('.env.local')  # or specify a path

database_url = os.getenv('DATABASE_URL')
print(database_url)

# --- Django: manage.py or settings.py ---
from dotenv import load_dotenv
from pathlib import Path

env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)

Go (godotenv)

Charger .env dans les projets Go :

// Install
// go get github.com/joho/godotenv

package main

import (
    "fmt"
    "log"
    "os"
    "github.com/joho/godotenv"
)

func main() {
    err := godotenv.Load()  // loads .env
    if err != nil {
        log.Fatal("Error loading .env file")
    }
    dbURL := os.Getenv("DATABASE_URL")
    fmt.Println(dbURL)
}

PHP (vlucas/phpdotenv)

Utilisé par Laravel et la plupart des frameworks PHP :

// Install
// composer require vlucas/phpdotenv

<?php
require 'vendor/autoload.php';

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

// Access variables
$dbUrl = $_ENV['DATABASE_URL'];
// or
$dbUrl = getenv('DATABASE_URL');

// Required variables (throws exception if missing)
$dotenv->required(['DATABASE_URL', 'API_KEY']);

Ruby (gem dotenv)

Utilisé par Rails et d'autres projets Ruby :

# Gemfile
gem 'dotenv-rails', groups: [:development, :test]

# Or for non-Rails Ruby:
gem 'dotenv'

# --- app.rb ---
require 'dotenv/load'
puts ENV['DATABASE_URL']

# --- Rails: .env is loaded automatically ---
# Access via ENV['DATABASE_URL'] anywhere in your app

Sécurité : ne jamais commiter les fichiers .env

Votre fichier .env contient des secrets (clés API, mots de passe de base de données, tokens). Le commiter dans le contrôle de version est l'erreur de sécurité n°1.

Patterns .gitignore

Ajoutez immédiatement ces patterns à votre fichier .gitignore :

# .gitignore

# Ignore all .env files
.env
.env.local
.env.*.local
.env.development
.env.production

# More aggressive pattern — ignore all .env variants
.env*

# But DO commit the example file
!.env.example

Utiliser .env.example

Commitez un fichier .env.example avec des valeurs vides pour que les coéquipiers sachent quelles variables sont requises :

# .env.example — commit this file
# Copy to .env and fill in your values

DATABASE_URL=
API_KEY=
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=
REDIS_URL=
JWT_SECRET=

# Optional
DEBUG=false
LOG_LEVEL=info

.env déjà commité ?

Si vous avez accidentellement commité un fichier .env, retirez-le du suivi et changez tous les secrets :

# Step 1: Remove .env from Git tracking (keeps local file)
git rm --cached .env

# Step 2: Add to .gitignore
echo ".env" >> .gitignore

# Step 3: Commit the removal
git add .gitignore
git commit -m "Remove .env from tracking, add to .gitignore"

# Step 4: CRITICAL — Rotate ALL secrets in the .env file
# Every API key, password, and token that was exposed
# must be regenerated immediately

Fichiers spécifiques à l'environnement

La plupart des frameworks supportent plusieurs fichiers .env pour différents environnements. Comprendre l'ordre de chargement est crucial.

Ordre de chargement (Next.js / Vite / CRA)

Les fichiers sont chargés dans cet ordre de priorité (les fichiers suivants écrasent les précédents) :

# Loading priority (highest to lowest):

# 1. Shell environment variables (always win)
# 2. .env.{NODE_ENV}.local   (e.g. .env.production.local)
# 3. .env.local               (NOT loaded in test)
# 4. .env.{NODE_ENV}          (e.g. .env.production)
# 5. .env                     (default fallback)

# Example for NODE_ENV=production:
# .env                     → loaded first (base defaults)
# .env.production          → overrides .env
# .env.local               → overrides .env.production
# .env.production.local    → overrides everything above

.env.local est toujours ignoré par git (ajoutez-le à .gitignore). Il n'est PAS chargé pendant les tests pour garder les tests déterministes.

Quel fichier pour quoi ?

FilePurposeGit
.envDefault values, non-secret configCommit
.env.exampleTemplate with empty valuesCommit
.env.localLocal secrets & overridesIgnore
.env.developmentDev-specific (shared)Commit
.env.productionProduction-specific (non-secret)Commit
.env.testTest environment configCommit
.env.production.localProduction secrets (local only)Ignore

Intégration Docker et Docker Compose

Directive env_file

Docker Compose peut charger les fichiers .env directement dans les conteneurs :

# docker-compose.yml (or compose.yml)
services:
  web:
    image: node:20-alpine
    env_file:
      - .env                  # base defaults
      - .env.production       # production overrides
    ports:
      - "3000:3000"

  db:
    image: postgres:16
    env_file:
      - .env.db               # separate file for DB secrets
    volumes:
      - pgdata:/var/lib/postgresql/data

environment vs env_file

Vous pouvez aussi définir les variables d'environnement en ligne. Voici la différence :

# Using env_file (loads from file)
services:
  web:
    env_file:
      - .env

# Using environment (inline)
services:
  web:
    environment:
      - NODE_ENV=production
      - PORT=3000
      - DATABASE_URL=${DATABASE_URL}   # from shell or .env

# Using environment (mapping syntax)
services:
  web:
    environment:
      NODE_ENV: production
      PORT: 3000
  • env_file : charge depuis un fichier, garde compose.yml propre, facile à changer par environnement.
  • environment : visible dans compose.yml, adapté aux valeurs non secrètes, supporte la substitution de variables.

.env pour les variables Docker Compose

Docker Compose lit automatiquement un fichier .env à la racine du projet pour la substitution de variables dans compose.yml :

# .env (in same directory as compose.yml)
POSTGRES_VERSION=16
NODE_VERSION=20
APP_PORT=3000

# compose.yml — uses .env for variable substitution
services:
  web:
    image: node:${NODE_VERSION}-alpine
    ports:
      - "${APP_PORT}:3000"

  db:
    image: postgres:${POSTGRES_VERSION}
    environment:
      POSTGRES_DB: myapp

10 erreurs .env courantes et corrections

Voici les problèmes .env les plus fréquents rencontrés par les développeurs :

#ErreurCauseCorrection
1process.env.VAR est undefineddotenv non chargé ou chargé après utilisationAppelez dotenv.config() tout en haut de votre fichier d'entrée
2Variables vides en productionFichier .env non déployé ; dépendance au fichier plutôt qu'aux variables de la plateformeDéfinissez les variables dans votre plateforme d'hébergement (Vercel, AWS, etc.)
3Les valeurs .env contiennent des guillemetsLe parseur traite les guillemets comme des caractères littérauxVérifiez la documentation du parseur
4Mauvais fichier .env chargéLe répertoire de travail diffère du chemin attenduUtilisez l'option path : dotenv.config({ path: ".env.local" })
5Valeur multiligne tronquéeValeur non correctement entre guillemets doublesEntourez les valeurs multilignes de guillemets doubles
6Les caractères spéciaux cassent la valeur$ ou # interprété comme interpolation/commentaireUtilisez des guillemets simples ou échappez avec \
7Erreur d'encodage BOMÉditeur Windows sauvegarde .env en UTF-8 BOMSauvegardez en UTF-8 sans BOM
8Variables d'environnement Docker videsChemin env_file incorrect ou fichier hors du contexte de buildVérifiez que le chemin est relatif à l'emplacement de compose.yml
9Espaces autour de = cassent le parsingKEY = VALUE au lieu de KEY=VALUESupprimez les espaces autour du signe égal
10Variables indisponibles dans le navigateur (React/Next)Préfixe requis manquant (NEXT_PUBLIC_ ou REACT_APP_)Ajoutez le préfixe requis par le framework pour exposer au code côté client

Alternatives en production

En production, les fichiers .env ne sont pas recommandés. Utilisez ces alternatives :

Variables d'environnement de la plateforme

Chaque plateforme d'hébergement majeure fournit une UI ou CLI pour définir les variables d'environnement :

# Vercel
vercel env add DATABASE_URL production
vercel env ls

# AWS (Parameter Store)
aws ssm put-parameter \
  --name "/myapp/prod/DATABASE_URL" \
  --value "postgres://..." \
  --type SecureString

# Heroku
heroku config:set DATABASE_URL=postgres://...
heroku config

# Railway
railway variables set DATABASE_URL=postgres://...

# Fly.io
fly secrets set DATABASE_URL=postgres://...

Docker Secrets

Pour Docker Swarm ou Compose, utilisez les secrets pour les données sensibles :

# compose.yml with Docker secrets
services:
  web:
    image: myapp:latest
    secrets:
      - db_password
      - api_key
    environment:
      DB_PASSWORD_FILE: /run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt    # for Compose
    # external: true                    # for Swarm
  api_key:
    file: ./secrets/api_key.txt

# In your app, read from file:
# const secret = fs.readFileSync('/run/secrets/db_password', 'utf8').trim();

Gestionnaires de secrets (Vault, AWS Secrets Manager)

Pour les applications d'entreprise, utilisez un gestionnaire de secrets dédié :

# HashiCorp Vault
vault kv put secret/myapp/production \
  DATABASE_URL="postgres://..." \
  API_KEY="sk-..."

# Read in application
vault kv get -field=DATABASE_URL secret/myapp/production

# AWS Secrets Manager
aws secretsmanager create-secret \
  --name "myapp/production/db" \
  --secret-string '{"url":"postgres://...","password":"..."}'

# Read in Node.js with AWS SDK
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
const client = new SecretsManager({ region: 'us-east-1' });
const { SecretString } = await client.getSecretValue({
  SecretId: 'myapp/production/db'
});
const secrets = JSON.parse(SecretString);

Les gestionnaires de secrets fournissent la rotation, les logs d'audit, le contrôle d'accès et le chiffrement au repos — des fonctionnalités que les fichiers .env ne peuvent pas offrir.

Questions fréquentes

Dois-je commiter mon fichier .env dans Git ?

Ne commitez jamais les fichiers .env contenant des secrets dans le contrôle de version. Commitez plutôt un fichier .env.example avec des valeurs vides. Ajoutez les patterns .env* à votre .gitignore.

Quelle est la différence entre .env, .env.local et .env.production ?

.env contient les valeurs par défaut chargées dans tous les environnements. .env.local contient les surcharges locales non commitées. .env.production contient les valeurs spécifiques à la production chargées uniquement quand NODE_ENV=production.

Pourquoi process.env.MY_VAR est undefined dans Node.js ?

Causes les plus courantes : 1) Oubli d'appeler require("dotenv").config() en haut du fichier d'entrée, 2) Le fichier .env n'est pas à la racine, 3) Faute de frappe dans le nom de variable, 4) Avec ES modules, utilisez "import dotenv/config".

Comment utiliser les variables .env dans Docker Compose ?

Docker Compose lit automatiquement un fichier .env dans le même répertoire que compose.yml pour la substitution de variables ${VAR}. Pour passer des variables aux conteneurs, utilisez env_file ou environment.

Peut-on utiliser les fichiers .env en production ?

Ce n'est pas recommandé. En production, utilisez les variables d'environnement de la plateforme, Docker secrets ou un gestionnaire de secrets comme HashiCorp Vault ou AWS Secrets Manager.

Comment exposer les variables .env au navigateur dans React ou Next.js ?

Dans Next.js, préfixez avec NEXT_PUBLIC_. Dans Create React App, utilisez REACT_APP_. Dans Vite, utilisez VITE_. Seules les variables préfixées sont intégrées dans le bundle client.

𝕏 Twitterin LinkedIn
Cet article vous a-t-il aidé ?

Restez informé

Recevez des astuces dev et les nouveaux outils chaque semaine.

Pas de spam. Désabonnez-vous à tout moment.

Essayez ces outils associés

🐳Docker Compose Generator.gi.gitignore GeneratorNXNginx Config Generator

Articles connexes

Aide-mémoire Docker Compose : Services, volumes et réseaux

Référence Docker Compose : définitions de services, volumes, réseaux, variables d'environnement et exemples de stacks.

Docker Compose env_file vs environment : Quand utiliser lequel (avec exemples)

Comprenez la différence entre env_file et environment dans Docker Compose. Cas d'usage, priorité des variables et configurations multi-environnement.