Les programmes contrôlent souvent le fonctionnement via la configuration fournie avec le logiciel, et les variables d'environnement permettent aux utilisateurs de les définir au moment de l'exécution. Cependant, l'exécution de processus dans des conteneurs Docker complique les choses, alors comment transmettre des variables d'environnement à un conteneur ?
À quoi servent les variables d'environnement ?
Les variables d'environnement permettent de dissocier la configuration de l'exécutable de l'application. Par exemple, vous ne voudriez pas stocker le mot de passe de votre base de données de production dans votre base de code. Si vous le faisiez, il serait visible depuis Git, et toute personne ayant accès à votre code pourrait supprimer votre base de données.
Au lieu de cela, vous le définissez avec une variable d'environnement, qui stocke une simple paire clé-valeur et vous permet d'accéder à la valeur dans n'importe quelle application exécutée dans la même session shell (elles ne sont pas accessibles globalement). Cela présente également l'avantage de pouvoir définir facilement différentes configurations pour différents environnements. Par exemple, avoir des clés distinctes pour les bases de données de développement et de production, ou utiliser un point de terminaison d'API différent.
La définition de ces variables pour les conteneurs Docker peut être effectuée de trois manières principales :avec des arguments CLI, .env
fichiers de configuration, ou via docker-compose
.
Avec un argument de ligne de commande
La commande utilisée pour lancer les conteneurs Docker, docker run
, accepte les variables ENV comme arguments. Exécutez-le simplement avec le -e
drapeau, raccourci pour --env
, et transmettez la paire clé=valeur :
sudo docker run -e POSTGRES_USER='postgres' -e POSTGRES_PASSWORD='password' ...
Et, si vous avez déjà défini ces variables d'environnement dans l'environnement qui exécute cette commande, vous pouvez simplement les transmettre directement par nom :
// set variable POSTGRES_PASSWORD='password' // use it later docker run -e POSTGRES_PASSWORD -e POSTGRES_USER ...
Sécurité supplémentaire avec un fichier .env
Passer des variables avec des arguments CLI fonctionne très bien, mais a un inconvénient :ces variables sont visibles depuis l'hôte. Ils sont enregistrés dans l'historique des commandes et visibles dans la liste des processus pour le processus lancé.
Linux a un moyen intégré de gérer les autorisations pour cet accès aux fichiers. Stocker les variables dans un .env
file vous permet de contrôler l'accès à ce fichier avec des autorisations de fichier (chmod
, chown
).
Créer un .env
fichier avec des variables au format suivant, chacune sur une nouvelle ligne :
POSTGRES_PASSWORD='password' POSTGRES_USER='postgres' APPLICATION_URL='example.com'
Ensuite, passez-le à docker run
avec le --env-file
drapeau :
docker run --env-file ./envfile ...
Avec Docker-Compose
Bien sûr, beaucoup de gens ne lancent pas les conteneurs Docker directement avec docker run
, et choisissez plutôt d'utiliser un docker-compose
fichier pour gérer la configuration de plusieurs conteneurs représentant tous une seule application.
Pour transmettre des variables d'environnement à un conteneur lancé de cette manière, vous devrez configurer le fichier de composition pour transmettre les variables de la session au conteneur Docker. Cette configuration passe ici le POSTGRES_USER
variable à la fois à l'environnement de construction et à l'environnement d'exécution, et définit une valeur par défaut si elle n'existe pas.
version: '3.1' services: my-service: build: context: . args: - POSTGRES_USER=${POSTGRES_USER:-default} environment: - POSTGRES_USER=${POSTGRES_USER:-default}
Vous devrez définir les variables d'environnement avant d'exécuter docker-compose up
, sinon il ne pourra pas y accéder. Vous pouvez les stocker dans le fichier de composition, mais cela est généralement suivi et versionné, ce qui va à l'encontre de l'objectif des variables env.
Avec Kubernetes
Kubernetes est un système d'orchestration capable de gérer l'exécution de centaines de conteneurs sur un réseau. Il utilise toujours Docker, mais vous ne touchez qu'à la configuration, donc le passage direct des variables d'environnement ne fonctionnera pas.
À la place, vous pouvez les définir dans la configuration du pod :
apiVersion: v1 kind: Pod metadata: name: example spec: containers: - ... env: - name: SERVICE_PORT value: "80" - name: SERVICE_IP value: "172.17.0.1"
Kubernetes est compliqué et il existe de nombreuses façons différentes de travailler avec des variables d'environnement. Pour en savoir plus, vous pouvez lire leurs guides sur l'injection de données dans les pods.