Les variables d'environnement expliquées (Linux, .env)
Une variable d’environnement est une valeur nommée, mise à disposition des programmes par le système d’exploitation. Elle sert à configurer un logiciel sans toucher à son code : indiquer où se trouve une base de données, régler le niveau de log, ou stocker une clé d’API. C’est le mécanisme universel pour séparer la configuration du code — un principe au cœur des applications modernes. Ce guide explique comment créer, lire et transmettre ces variables sous Linux, comment les regrouper dans un fichier .env, et comment les manipuler depuis Node, Python et PHP, sans jamais exposer ses secrets.
Lire et créer une variable dans le terminal
Le système en définit déjà beaucoup. Pour en afficher une, on la préfixe d’un $ :
echo $HOME
echo $PATH
Pour lister toutes les variables de la session courante :
printenv # ou : env
Quelques classiques : HOME (dossier personnel), USER, PATH (où chercher les exécutables), LANG, SHELL, PWD.
Créer une variable : simple assignation vs export
Une assignation simple crée une variable de shell, visible seulement dans le terminal courant :
MON_APP_MODE=dev
echo $MON_APP_MODE # dev
Mais si vous lancez un programme, il ne la verra pas. Pour qu’une variable soit héritée par les processus enfants — c’est-à-dire devienne une vraie variable d’environnement — il faut l’exporter :
export MON_APP_MODE=dev
C’est toute la différence : export transmet la variable aux commandes que vous lancez ensuite. On peut aussi la définir juste pour une commande, en préfixe :
NODE_ENV=production node server.js
Ici NODE_ENV n’existe que le temps de cette exécution, sans polluer le shell. Pour supprimer une variable : unset MON_APP_MODE.
Rendre une variable permanente : .bashrc et .profile
Une variable exportée disparaît à la fermeture du terminal. Pour qu’elle soit définie à chaque session, on l’ajoute à un fichier de configuration du shell. Encore faut-il choisir le bon.
~/.bashrcest lu à l’ouverture d’un shell interactif non-login (un nouvel onglet de terminal). C’est le fichier le plus utilisé au quotidien.~/.profile(ou~/.bash_profile) est lu par un shell login — connexion SSH, ouverture de session graphique. C’est le bon endroit pour les variables qui doivent exister dans toute la session utilisateur, y compris les applications lancées hors terminal.
En pratique, pour une variable de développeur ordinaire, ~/.bashrc suffit. Ajoutez-y la ligne :
export EDITOR=nano
export PATH="$HOME/.local/bin:$PATH"
Puis rechargez le fichier sans rouvrir le terminal :
source ~/.bashrc
Si vous utilisez Zsh (le shell par défaut de macOS), l’équivalent est ~/.zshrc. Notez la façon d’étendre PATH en préservant l’existant : on ré-affecte PATH en y insérant le nouveau dossier suivi de $PATH. Ces mêmes variables sont d’ailleurs souvent nécessaires aux tâches planifiées, dont l’environnement est réduit — un point détaillé dans notre guide sur cron sous Linux.
Les fichiers .env : centraliser la configuration d’un projet
Exporter les variables à la main n’a pas de sens quand un projet en compte quinze. La convention moderne est de les regrouper dans un fichier .env à la racine du projet :
# .env
APP_ENV=development
DATABASE_URL=postgres://user:pass@localhost:5432/mabase
API_KEY=sk_test_51H8xY2eZvKq
PORT=3000
La syntaxe est volontairement minimale : une paire CLE=valeur par ligne, pas d’espaces autour du =, des commentaires avec #. Ce fichier n’est pas chargé automatiquement par le système : c’est votre application (ou une bibliothèque) qui le lit au démarrage.
On peut aussi le charger manuellement dans un shell pour tester une commande :
set -a # marque les variables suivantes pour export
source .env
set +a
Lire les variables depuis un programme
Chaque langage expose l’environnement du processus. Voici les trois cas les plus courants.
Node.js
Node lit l’environnement via l’objet process.env :
const port = process.env.PORT || 3000;
const apiKey = process.env.API_KEY;
console.log(`Démarrage sur le port ${port}`);
Pour charger automatiquement un fichier .env, la bibliothèque de référence est dotenv :
npm install dotenv
import 'dotenv/config'; // charge .env dans process.env
console.log(process.env.DATABASE_URL);
Depuis les versions récentes, Node sait aussi le faire nativement avec le drapeau --env-file :
node --env-file=.env server.js
Python
Python passe par le module os :
import os
port = os.environ.get("PORT", "3000") # valeur par défaut si absente
api_key = os.environ["API_KEY"] # lève une erreur si manquante
Pour charger un .env, on utilise python-dotenv :
pip install python-dotenv
from dotenv import load_dotenv
import os
load_dotenv()
print(os.getenv("DATABASE_URL"))
La distinction entre os.environ["X"] (échoue si absent) et os.environ.get("X") (renvoie None) est importante : préférez la version stricte pour les variables réellement obligatoires, afin d’échouer tôt et clairement.
PHP
PHP expose l’environnement via getenv() et la superglobale $_ENV :
$dbUrl = getenv('DATABASE_URL');
$port = $_ENV['PORT'] ?? 3000;
Dans l’écosystème Symfony ou Laravel, le chargement du .env est intégré au framework via la bibliothèque symfony/dotenv, et l’accès se fait directement par $_ENV ou une fonction env().
Bonnes pratiques : ne jamais fuiter ses secrets
Les variables d’environnement contiennent souvent des données sensibles : mots de passe, clés d’API, jetons. Quelques règles évitent les incidents.
Ne jamais committer le fichier .env
C’est la règle d’or. Ajoutez-le tout de suite à votre .gitignore :
# .gitignore
.env
.env.local
.env.*.local
À la place, versionnez un fichier d’exemple sans valeurs réelles, qui documente les variables attendues :
# .env.example
APP_ENV=
DATABASE_URL=
API_KEY=
PORT=3000
Chaque développeur copie .env.example en .env et remplit ses propres valeurs. Si vous découvrez qu’un secret a déjà été poussé sur un dépôt, le retirer du dernier commit ne suffit pas : considérez-le compromis et régénérez-le côté fournisseur.
Autres réflexes
- Séparez les environnements : des valeurs différentes en développement, en test et en production. Ne pointez jamais un
.envde dev vers la base de production. - En production, préférez l’injection par la plateforme (variables du panneau d’hébergement, secrets Docker, variables CI/CD) plutôt qu’un fichier
.envdéposé sur le serveur. - Restreignez les permissions du fichier s’il existe sur un serveur :
chmod 600 .envpour qu’il ne soit lisible que par son propriétaire. - Ne les affichez pas dans les logs : un
console.log(process.env)malheureux peut recopier une clé secrète dans un fichier de log lisible.
Ces variables se marient bien avec l’automatisation : un script Bash peut sourcer un .env avant de lancer un déploiement, en gardant les secrets hors du code.
En résumé
Retenez la mécanique : une assignation simple reste locale au shell, export la transmet aux programmes, ~/.bashrc la rend permanente. Pour un projet, un fichier .env centralise la configuration, chargé par dotenv ou nativement selon le langage. Et par-dessus tout, un principe de sécurité non négociable : le code va sur Git, les secrets restent dehors. En appliquant cette séparation dès le premier commit, vous vous épargnez la classe de bugs et de fuites la plus coûteuse de la vie d’un projet.