Comment transmettre des variables d'environnement aux conteneurs Docker?
Je suis nouveau sur Docker, et on ne sait pas comment accéder à une base de données externe à partir d'un conteneur. Est la meilleure façon de coder en dur dans la chaîne de connexion?
# Dockerfile
ENV DATABASE_URL amazon:rds/connection?string
8 réponses
Vous pouvez passer des variables d'environnement à vos conteneurs avec l'indicateur -e
.
Un exemple d'un script de démarrage:
sudo docker run -d -t -i -e REDIS_NAMESPACE='staging' \
-e POSTGRES_ENV_POSTGRES_PASSWORD='foo' \
-e POSTGRES_ENV_POSTGRES_USER='bar' \
-e POSTGRES_ENV_DB_NAME='mysite_staging' \
-e POSTGRES_PORT_5432_TCP_ADDR='docker-db-1.hidden.us-east-1.rds.amazonaws.com' \
-e SITE_URL='staging.mysite.com' \
-p 80:80 \
--link redis:redis \
--name container_name dockerhub_id/image_name
Ou, si vous ne voulez pas avoir la valeur sur la ligne de commande où elle sera affichée par ps
, etc., -e
peut extraire la valeur de l'environnement actuel si vous le donnez simplement sans =
:
sudo PASSWORD='foo' docker run [...] -e PASSWORD [...]
Si vous avez beaucoup de variables d'environnement et surtout si elles sont censées être secrètes, vous pouvez utiliser un env-fichier:
$ docker run --env-file ./env.list ubuntu bash
L'indicateur --env-file prend un nom de fichier comme argument et attend que chaque ligne soit au format VAR=VAL, imitant l'argument passé à --env. Les lignes de commentaire ne doivent être préfixées que par #
Vous pouvez passer en utilisant -e
paramètres avec docker run ..
commande comme mentionné ici et comme mentionné par @errata.
Cependant, l'inconvénient de cette approche est que vos informations seront affichées dans la liste des processus, lorsque vous l'exécutez.
Pour le rendre plus sûr, vous pouvez écrire vos informations d'identification dans un fichier de configuration et faire docker run
avec --env-file
comme mentionné ici. Ensuite, vous pouvez contrôler l'accès à ce fichier de configuration afin que les autres ayant accès à cette machine Je ne verrais pas vos informations d'identification.
Si vous utilisez 'docker-compose' comme méthode pour faire tourner votre (vos) conteneur (s), il existe un moyen utile de passer une variable d'environnement définie sur votre serveur au conteneur docker.
Dans votre fichier docker-compose.yml
, disons que vous créez un conteneur Hapi-js de base et que le code ressemble à:
hapi_server:
container_name: hapi_server
image: node_image
expose:
- "3000"
Disons que le serveur local sur lequel se trouve votre projet docker a une variable d'environnement nommée 'NODE_DB_CONNECT' que vous souhaitez transmettre à votre conteneur hapi - JS, et vous voulez que son nouveau nom soit 'HAPI_DB_CONNECT'. Ensuite, dans le fichier docker-compose.yml
, vous passerez la variable d'environnement locale au conteneur et la renommerez comme suit:
hapi_server:
container_name: hapi_server
image: node_image
environment:
- HAPI_DB_CONNECT=${NODE_DB_CONNECT}
expose:
- "3000"
J'espère que cela vous aidera à éviter de coder en dur une chaîne de connexion de base de données dans n'importe quel fichier de votre conteneur!
Utilisez la valeur -e
ou --env pour définir les variables d'environnement (par défaut []).
Un exemple d'un script de démarrage:
docker run -e myhost='localhost' -it busybox sh
Si vous souhaitez utiliser plusieurs environnements à partir de la ligne de commande, avant chaque variable d'environnement, utilisez l'indicateur -e
.
Exemple:
sudo docker run -d -t -i -e NAMESPACE='staging' -e PASSWORD='foo' busybox sh
Remarque: assurez-vous de mettre le nom du conteneur après la variable d'environnement, pas avant.
Si vous devez configurer plusieurs variables, utilisez l'indicateur --env-file
Pour exemple,
$ docker run --env-file ./my_env ubuntu bash
Pour toute autre aide, consultez l'aide Docker:
$ docker run --help
Documentation officielle: https://docs.docker.com/compose/environment-variables/
En utilisant docker-compose
, l'exemple ci-dessous montre comment vous pouvez hériter des variables shell env dans les deux docker-compose.yml et à son tour tout Dockerfile(S) appelé (s) par docker-compose
pour construire des images. J'ai trouvé cela utile si disons dans le Dockerfile
RUN
commande j'ai besoin d'exécuter des commandes spécifiques à l'environnement.
(votre shell a RAILS_ENV=development
déjà existants dans l'environnement)
Docker-composer.yml :
version: '3.1'
services:
my-service:
build:
#$RAILS_ENV is referencing the shell environment RAILS_ENV variable
#and passing it to the Dockerfile ARG RAILS_ENV
#the syntax below ensures that the RAILS_ENV arg will default to
#production if empty.
#note that is dockerfile: is not specified it assumes file name: Dockerfile
context: .
args:
- RAILS_ENV=${RAILS_ENV:-production}
environment:
- RAILS_ENV=${RAILS_ENV:-production}
Dockerfile:
FROM ruby:2.3.4
#give ARG RAILS_ENV a default value = production
ARG RAILS_ENV=production
#assign the $RAILS_ENV arg to the RAILS_ENV ENV so that it can be accessed
#by the subsequent RUN call within the container
ENV RAILS_ENV $RAILS_ENV
#the subsequent RUN call accesses the RAILS_ENV ENV variable within the container
RUN if [ "$RAILS_ENV" = "production" ] ; then echo "production env"; else echo "non-production env: $RAILS_ENV"; fi
De cette façon, je n'ai pas besoin de spécifiez les variables d'environnement dans les fichiers ou docker-compose
build
/up
commandes:
docker-compose build
docker-compose up
Pour Amazon AWS ECS / ECR, vous devez gérer vos variables d'environnement (en particulier Les secrets ) via un compartiment S3 privé. Voir le billet de blogComment gérer les Secrets pour les applications basées sur le service de conteneurs Amazon EC2 en utilisant Amazon S3 et Docker.
Un Autre moyen est d'utiliser les pouvoirs de /usr/bin/env
:
docker run ubuntu env DEBUG=1 path/to/script.sh
Si vous avez les variables d'environnement dans un env.sh
localement et souhaitez le configurer lorsque le conteneur commence, vous pouvez essayer de
COPY env.sh /env.sh
COPY <filename>.jar /<filename>.jar
ENTRYPOINT ["/bin/bash" , "-c", "source /env.sh && printenv && java -jar /<filename>.jar"]
Cette commande démarrera le conteneur avec un shell bash (je veux un shell bash puisque source
est une commande bash), source le fichier env.sh
(qui définit les variables d'environnement) et exécute le fichier jar.
Le env.sh
ressemble à ça,
#!/bin/bash
export FOO="BAR"
export DB_NAME="DATABASE_NAME"
J'ai ajouté la commande printenv
Uniquement pour tester que la commande source réelle fonctionne. Vous devriez probablement supprimez-le lorsque vous confirmez que la commande source fonctionne correctement ou que les variables d'environnement apparaissent dans vos journaux docker.