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
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 #
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.
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!
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/
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 Dockerfile
RUN
, 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-compose
build
/up
:
docker-compose build
docker-compose up
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 versenv_file
et les rendra accessibles dans le conteneur en cours d'exécution.
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.
Une autre façon consiste à utiliser les pouvoirs de /usr/bin/env
:
docker run ubuntu env DEBUG=1 path/to/script.sh
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.
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)