Une application prête pour la production ne contient aucun secret, aucun mot de passe ni aucune URL spécifique codés en dur dans son code source. Selon le 3ème principe Twelve-Factor, la configuration doit être strictement découplée du code et injectée au runtime.
Le même code compilé doit pouvoir tourner en Dev, Test ou Prod sans changer une seule ligne de code.
.env et .env.local ne doivent jamais être commités dans Git sous peine d'alerte de sécurité critique.
Le seul fichier commité : il liste toutes les clés requises avec des valeurs factices pour guider l'équipe.
Crucial : toute variable injectée dans un frontend (Angular, React) est publique et visible dans le navigateur.
Testez l'affectation d'une variable pour comprendre si son utilisation présente un danger critique de fuite de données :
Vous tentez d'injecter "DATABASE_URL" dans le Frontend ! N'importe qui ouvrant l'inspecteur web (F12) pourra extraire ce secret et pirater votre base de données ou vos comptes de paiement !
Le navigateur n'a pas accès au terminal du serveur. Lors de npm run build, les variables préfixées (ex: VITE_ ou NG_APP_) sont remplacées textuellement en dur dans le bundle JavaScript minifié !
pk_live_...). Jamais de secret ! Le code s'exécute sur le serveur ou dans un conteneur Docker. Les variables sont lues dynamiquement depuis la mémoire système du processus (process.env) et ne transitent jamais sur le réseau vers le client.
sk_live_...), tokens JWT et identifiants de base de données. Si une variable obligatoire est oubliée dans le panneau de l'hébergeur, votre application ne doit pas démarrer silencieusement pour planter plus tard en pleine requête client. Validez votre environnement dès le boot :
// config/env.validator.ts (Fail-Fast pattern avec Zod)
import { z } from 'zod';
import dotenv from 'dotenv';
dotenv.config();
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
PORT: z.string().transform(Number).default('3000'),
DATABASE_URL: z.string().url("DATABASE_URL doit être une URL valide"),
JWT_SECRET: z.string().min(32, "Le secret JWT doit faire au moins 32 caractères"),
PUBLIC_FRONTEND_URL: z.string().url()
});
// Analyse et validation dès le démarrage du serveur
const parsed = envSchema.safeParse(process.env);
if (!parsed.success) {
console.error("❌ ERREUR DE CONFIGURATION CRITIQUE : Variables d'environnement manquantes :");
console.error(parsed.error.format());
process.exit(1); // Arrêt immédiat avant d'écouter les requêtes !
}
export const env = parsed.data;