Ich bin neu in Docker und es ist unklar, wie von einem Container aus auf eine externe Datenbank zugegriffen werden kann. Ist der beste Weg, die Verbindungszeichenfolge fest zu codieren?
# Dockerfile
ENV DATABASE_URL Amazon:rds/connection?string
Sie können Umgebungsvariablen mit dem Flag -e
an Ihre Container übergeben.
Ein Beispiel aus einem Startskript:
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
Wenn Sie den Wert nicht in der Befehlszeile haben möchten, in der er von ps
usw. angezeigt wird, kann -e
den Wert aus der aktuellen Umgebung übernehmen, wenn Sie ihn nur eingeben es ohne den =
:
Sudo PASSWORD='foo' docker run [...] -e PASSWORD [...]
Wenn Sie viele Umgebungsvariablen haben und diese besonders geheim sein sollen, können Sie verwenden Sie eine env-Datei :
$ docker run --env-file ./env.list ubuntu bash
Das Flag --env-file nimmt einen Dateinamen als Argument und erwartet, dass jede Zeile das Format VAR = VAL hat, was das an --env übergebene Argument imitiert. Kommentarzeilen müssen nur mit # vorangestellt werden
Sie können die -e
-Parameter mit dem docker run ..
-Befehl übergeben, wie unter hier und wie unter @errata angegeben.
Der mögliche Nachteil dieses Ansatzes ist jedoch, dass Ihre Anmeldeinformationen in der Prozessliste angezeigt werden, in der Sie sie ausführen.
Um die Sicherheit zu erhöhen, können Sie Ihre Anmeldeinformationen in eine Konfigurationsdatei schreiben und docker run
mit --env-file
wie erwähnt ausführen hier . Dann können Sie den Zugriff auf diese Konfigurationsdatei so steuern, dass andere Benutzer, die Zugriff auf diesen Computer haben, Ihre Anmeldeinformationen nicht sehen können.
Wenn Sie 'docker-compose' als Methode zum Hochfahren Ihrer Container verwenden, gibt es eine nützliche Möglichkeit, eine auf Ihrem Server definierte Umgebungsvariable an den Docker-Container zu übergeben.
Nehmen wir an, Sie drehen in Ihrer docker-compose.yml
-Datei einen einfachen hapi-js-Container und der Code sieht folgendermaßen aus:
hapi_server:
container_name: hapi_server
image: node_image
expose:
- "3000"
Angenommen, der lokale Server, auf dem sich Ihr Docker-Projekt befindet, hat eine Umgebungsvariable mit dem Namen 'NODE_DB_CONNECT', die Sie an Ihren hapi-js-Container übergeben möchten, und der neue Name soll 'HAPI_DB_CONNECT' lauten. Dann würden Sie in der Datei docker-compose.yml
die lokale Umgebungsvariable an den Container übergeben und wie folgt umbenennen:
hapi_server:
container_name: hapi_server
image: node_image
environment:
- HAPI_DB_CONNECT=${NODE_DB_CONNECT}
expose:
- "3000"
Ich hoffe, dies hilft Ihnen dabei, die harte Kodierung einer Datenbankverbindungszeichenfolge in einer beliebigen Datei in Ihrem Container zu vermeiden!
Verwenden Sie -e
oder --env, um Umgebungsvariablen festzulegen (Standardeinstellung []).
Ein Beispiel aus einem Startskript:
docker run -e myhost='localhost' -it busybox sh
Wenn Sie mehrere Umgebungen über die Befehlszeile verwenden möchten, verwenden Sie vor jeder Umgebungsvariablen das -e
-Flag.
Beispiel:
Sudo docker run -d -t -i -e NAMESPACE='staging' -e PASSWORD='foo' busybox sh
Hinweis: Stellen Sie sicher, dass der Containername nach der Umgebungsvariablen und nicht davor steht.
Wenn Sie viele Variablen einrichten müssen, verwenden Sie das Flag --env-file
Zum Beispiel,
$ docker run --env-file ./my_env ubuntu bash
Weitere Hilfe finden Sie in der Docker-Hilfe:
$ docker run --help
Offizielle Dokumentation: https://docs.docker.com/compose/environment-variables/
Mit docker-compose
zeigt das folgende Beispiel, wie Sie Shell-Umgebungsvariablen sowohl in docker-compose.yml als auch in Docker-Dateien erben können, die von docker-compose
aufgerufen werden, um Bilder zu erstellen. Ich fand dies nützlich, wenn Sie im Befehl Dockerfile
RUN
sagen, dass ich umgebungsspezifische Befehle ausführen muss.
(Ihre Shell hat Rails_ENV=development
bereits in der Umgebung vorhanden)
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
Auf diese Weise muss ich keine Umgebungsvariablen in Dateien oder docker-compose
build
/up
-Befehlen angeben:
docker-compose build
docker-compose up
Es gibt einen netten Hack, wie Umgebungsvariablen des Host-Rechners an einen Docker-Container weitergeleitet werden:
env > env_file && docker run --env-file env_file image_name
Wenden Sie diese Technik sehr sorgfältig an, da
env > env_file
ALL ENV-Variablen des Host-Computers inenv_file
ablegt und im laufenden Container zugänglich macht.
Für Amazon AWS ECS/ECR sollten Sie Ihre Umgebungsvariablen (, insbesondere Geheimnisse ) über einen privaten S3-Bucket verwalten. Siehe Blog-Beitrag Verwalten von Geheimnissen für Amazon EC2-Anwendungen mit Containerdiensten mithilfe von Amazon S3 und Docker.
Ein anderer Weg ist, die Kräfte von /usr/bin/env
zu nutzen:
docker run ubuntu env DEBUG=1 path/to/script.sh
Wenn Sie die Umgebungsvariablen in einem env.sh
lokal haben und sie beim Start des Containers einrichten möchten, können Sie es versuchen
COPY env.sh /env.sh
COPY <filename>.jar /<filename>.jar
ENTRYPOINT ["/bin/bash" , "-c", "source /env.sh && printenv && Java -jar /<filename>.jar"]
Dieser Befehl würde den Container mit einer Bash-Shell starten (ich möchte eine Bash-Shell, da source
ein Bash-Befehl ist), die Datei env.sh
(die die Umgebungsvariablen festlegt) ausgeben und die JAR-Datei ausführen.
Der env.sh
sieht so aus,
#!/bin/bash
export FOO="BAR"
export DB_NAME="DATABASE_NAME"
Ich habe den Befehl printenv
hinzugefügt, um zu testen, ob der eigentliche Quellbefehl funktioniert. Sie sollten es wahrscheinlich entfernen, wenn Sie bestätigen, dass der Quellbefehl ordnungsgemäß funktioniert oder die Umgebungsvariablen in Ihren Docker-Protokollen angezeigt werden.
Verwenden von jq zum Konvertieren von env in JSON:
env_as_json=`jq -c -n env`
docker run -e Host_ENV="$env_as_json" <image>
dies erfordert die jq-Version 1.6 oder neuer
dieses pust das Host-Env als json, im Wesentlichen so wie in Dockerfile:
ENV Host_ENV (all env from the Host as json)