web-dev-qa-db-fra.com

Comment transmettre des variables d'environnement aux conteneurs Docker?

Je connais Docker pour la première fois et je ne sais pas comment accéder à une base de données externe à partir d'un conteneur. Est-ce le meilleur moyen de coder en dur dans la chaîne de connexion?

# Dockerfile
ENV DATABASE_URL Amazon:rds/connection?string
683
AJcodez

Vous pouvez transmettre des variables d'environnement à vos conteneurs avec l'indicateur -e.

Un exemple tiré 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 que la valeur sur la ligne de commande soit affichée par ps, etc., -e peut extraire la valeur de l'environnement actuel si vous ne donnez que sans le =:

Sudo PASSWORD='foo' docker run  [...] -e PASSWORD [...]

Si vous avez plusieurs variables d'environnement et surtout si elles sont censées être secrètes, vous pouvez tiliser un fichier env :

$ docker run --env-file ./env.list ubuntu bash

L'indicateur --env-file prend un nom de fichier comme argument et s'attend à ce que chaque ligne soit au format VAR = VAL, imitant l'argument transmis à --env. Les lignes de commentaire doivent seulement être précédées de #

1032
errata

Vous pouvez passer en utilisant les paramètres -e avec la commande docker run .. comme indiqué ici et comme indiqué par @errata.
Toutefois, cette approche présente l’inconvénient possible que vos informations d’identité soient affichées dans la liste des processus, où vous les exécutez.
Pour plus de sécurité, vous pouvez écrire vos identifiants dans un fichier de configuration et faire docker run avec --env-file comme indiqué ici . Ensuite, vous pouvez contrôler l'accès à ce fichier de configuration afin que les autres utilisateurs ayant accès à cette machine ne voient pas vos informations d'identification.

86
Sabin

Si vous utilisez 'docker-compose' comme méthode de rotation de votre/vos conteneur (s), il existe un moyen utile de transmettre 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 à ceci:

hapi_server:
  container_name: hapi_server
  image: node_image
  expose:
    - "3000"

Supposons que le serveur local sur lequel se trouve votre projet de menu fixe comporte une variable d'environnement nommée 'NODE_DB_CONNECT' que vous souhaitez transmettre à votre conteneur hapi-js et que vous souhaitez que son nouveau nom soit 'HAPI_DB_CONNECT'. Ensuite, dans le fichier docker-compose.yml, vous transmettriez la variable d’environnement local au conteneur et vous le renommeriez ainsi:

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 à la base de données dans tous les fichiers de votre conteneur!

46
Marquistador

Utilisez la valeur -e ou --env pour définir les variables d’environnement (par défaut []).

Un exemple tiré 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, vous devez utiliser le drapeau -e avant chaque variable d'environnement.

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

Par exemple,

 $ docker run --env-file ./my_env ubuntu bash

Pour toute autre aide, consultez l'aide de Docker:

 $ docker run --help

Documentation officielle: https://docs.docker.com/compose/environment-variables/

23
Vishnu Mishra

En utilisant docker-compose, l'exemple ci-dessous montre comment vous pouvez hériter des variables d'environnement Shell à la fois dans docker-compose.yml et, éventuellement, dans tout fichier Docker appelé par docker-compose pour construire des images. J'ai trouvé cela utile si, par exemple, dans la commande DockerfileRUN, j'ai besoin d'exécuter des commandes spécifiques à l'environnement.

(votre shell a Rails_ENV=development déjà existant dans l'environnement)

docker-compose.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écifier les variables d'environnement dans les fichiers ou les commandes docker-composebuild/up:

docker-compose build
docker-compose up
19
joshweir

Il y a une bonne astuce comment canaliser les variables d'environnement de la machine hôte vers un conteneur de menu fixe:

env > env_file && docker run --env-file env_file image_name

Utilisez cette technique avec précaution, car env > env_file dumpera ALL Variables ENV de la machine hôte vers env_file et les rendra accessibles dans le conteneur en cours d'exécution.

8
Alex T

Pour Amazon AWS ECS/ECR, vous devez gérer vos variables d'environnement (, notamment les secrets ) via un compartiment S3 privé. Voir l'article de blog Comment gérer les secrets pour les applications basées sur Amazon EC2 Container Service à l'aide d'Amazon S3 et de Docker.

4
Joseph Juhnke

Une autre façon consiste à utiliser les pouvoirs de /usr/bin/env:

docker run ubuntu env DEBUG=1 path/to/script.sh
4
sanmai

Si vous avez localement les variables d’environnement dans un env.sh et que vous souhaitez le configurer au démarrage du conteneur, vous pouvez essayer

COPY env.sh /env.sh
COPY <filename>.jar /<filename>.jar
ENTRYPOINT ["/bin/bash" , "-c", "source /env.sh && printenv && Java -jar /<filename>.jar"]

Cette commande permet de démarrer le conteneur avec un shell bash (je veux un shell bash car 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 à ceci,

#!/bin/bash
export FOO="BAR"
export DB_NAME="DATABASE_NAME"

J'ai ajouté la commande printenv uniquement pour vérifier que la commande source réelle fonctionne. Vous devez probablement le supprimer lorsque vous confirmez que la commande source fonctionne correctement ou que les variables d'environnement apparaissent dans les journaux de votre menu fixe.

2
akilesh raj

Utiliser jq pour convertir env en JSON:

env_as_json=`jq -c -n env`
docker run -e Host_ENV="$env_as_json" <image>

cela nécessite la version jq 1.6 ou plus récente

cela donne envie à l'hôte de json, comme dans Dockerfile:

ENV Host_ENV  (all env from the Host as json)
0
Alexander Mills