Odpowiedzi:
Możesz przekazać zmienne środowiskowe do swoich kontenerów za pomocą -e
flagi.
Przykład ze skryptu uruchamiania:
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
Lub, jeśli nie chcesz, aby wartość w wierszu polecenia, w której będzie wyświetlana przez ps
itd., -e
Może pobrać wartość z bieżącego środowiska, jeśli podasz ją bez =
:
sudo PASSWORD='foo' docker run [...] -e PASSWORD [...]
Jeśli masz wiele zmiennych środowiskowych, a zwłaszcza jeśli mają one być tajne, możesz użyć pliku env :
$ docker run --env-file ./env.list ubuntu bash
Flaga --env-file przyjmuje nazwę pliku jako argument i oczekuje, że każda linia ma format VAR = VAL, naśladując argument przekazany do --env. Wiersze komentarza muszą być poprzedzone tylko znakiem #
export PASSWORD=foo
a zmienna zostanie przekazana docker run
jako zmienna środowiskowa, dzięki czemu będzie docker run -e PASSWORD
działać.
Możesz przekazać za pomocą -e
parametrów z docker run ..
poleceniem, jak wspomniano tutaj i jak wspomniano w @errata.
Jednak możliwym minusem tego podejścia jest to, że twoje poświadczenia będą wyświetlane na liście procesów, gdzie je uruchomisz.
Aby zwiększyć bezpieczeństwo, możesz zapisać swoje poświadczenia w pliku konfiguracyjnym i postępować zgodnie docker run
z --env-file
opisem tutaj . Następnie możesz kontrolować dostęp do tego pliku konfiguracyjnego, aby inne osoby mające dostęp do tego komputera nie widziały twoich poświadczeń.
--env-file
, kiedy użyjesz --env
wartości env, będą one cytowane / oznaczone znakami ucieczki ze standardową semantyką jakiejkolwiek powłoki, której używasz, ale kiedy użyjesz --env-file
wartości, które dostaniesz się do kontenera, będzie inaczej. Komenda uruchamiania dokera po prostu odczytuje plik, wykonuje bardzo podstawowe analizowanie i przekazuje wartości do kontenera, nie jest to równoważne z zachowaniem powłoki. Wystarczy mała uwaga, jeśli chcesz przekonwertować kilka --env
wpisów na --env-file
.
Jeśli używasz metody „docker-compose” jako metody rozbijania kontenerów, istnieje faktycznie przydatny sposób przekazania zmiennej środowiskowej zdefiniowanej na serwerze do kontenera Docker.
W twoim docker-compose.yml
pliku załóżmy, że rozpakowujesz podstawowy kontener hapi-js, a kod wygląda następująco:
hapi_server:
container_name: hapi_server
image: node_image
expose:
- "3000"
Powiedzmy, że lokalny serwer, na którym znajduje się projekt dokera, ma zmienną środowiskową o nazwie „NODE_DB_CONNECT”, którą chcesz przekazać do kontenera hapi-js, i chcesz, aby jego nowa nazwa brzmiała „HAPI_DB_CONNECT”. Następnie w docker-compose.yml
pliku przekazujesz lokalną zmienną środowiskową do kontenera i zmieniasz jej nazwę w następujący sposób:
hapi_server:
container_name: hapi_server
image: node_image
environment:
- HAPI_DB_CONNECT=${NODE_DB_CONNECT}
expose:
- "3000"
Mam nadzieję, że pomoże to uniknąć zakodowania na stałe ciągu połączenia z bazą danych w dowolnym pliku w kontenerze!
Za pomocą docker-compose
można dziedziczyć zmienne env w pliku docker-compose.yml, a następnie w dowolnym pliku Docker, do którego są wywoływane docker-compose
kompilacje obrazów. Jest to przydatne, gdy Dockerfile
RUN
polecenie powinno wykonywać polecenia specyficzne dla środowiska.
(twoja powłoka RAILS_ENV=development
już istnieje w środowisku)
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}
Plik Docker :
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
W ten sposób dont potrzebę określenia zmiennych środowiskowych w plikach lub docker-compose
build
/ up
poleceń:
docker-compose build
docker-compose up
Użyj -e
lub --env, aby ustawić zmienne środowiskowe (domyślnie []).
Przykład ze skryptu uruchamiania:
docker run -e myhost='localhost' -it busybox sh
Jeśli chcesz używać wielu środowisk z wiersza poleceń, to przed każdą zmienną środowiskową użyj -e
flagi.
Przykład:
sudo docker run -d -t -i -e NAMESPACE='staging' -e PASSWORD='foo' busybox sh
Uwaga: pamiętaj, aby umieścić nazwę kontenera za zmienną środowiskową, a nie wcześniej.
Jeśli musisz skonfigurować wiele zmiennych, użyj --env-file
flagi
Na przykład,
$ docker run --env-file ./my_env ubuntu bash
Aby uzyskać inną pomoc, zajrzyj do pomocy Dockera:
$ docker run --help
Oficjalna dokumentacja: https://docs.docker.com/compose/environment-variables/
ubuntu bash
? Czy ma to zastosowanie do obrazów utworzonych za pomocą ubuntu jako obrazu podstawowego czy do każdego obrazu?
-e
argumentach sprzed wieków! Nie mogę nawet zrozumieć, dlaczego sprawili, że stało się to konieczne ...
Jest fajny hack, w jaki sposób potokować zmienne środowiskowe komputera hosta do kontenera dokującego:
env > env_file && docker run --env-file env_file image_name
Użyj tej techniki bardzo ostrożnie, ponieważ
env > env_file
zrzuci WSZYSTKIE zmienne ENV maszyny hostaenv_file
i udostępni je w uruchomionym kontenerze.
W przypadku Amazon AWS ECS / ECR powinieneś zarządzać swoimi zmiennymi środowiskowymi ( zwłaszcza tajnymi ) za pośrednictwem prywatnego segmentu S3. Zobacz post na blogu Jak zarządzać sekretami dla aplikacji opartych na usługach kontenerowych Amazon EC2 za pomocą Amazon S3 i Docker .
Jeśli masz zmienne środowiskowe env.sh
lokalnie i chcesz je skonfigurować podczas uruchamiania kontenera, możesz spróbować
COPY env.sh /env.sh
COPY <filename>.jar /<filename>.jar
ENTRYPOINT ["/bin/bash" , "-c", "source /env.sh && printenv && java -jar /<filename>.jar"]
To polecenie uruchomiłoby kontener z powłoką bash (chcę powłoki bash, ponieważ source
jest to polecenie bash), źródło env.sh
pliku (który ustawia zmienne środowiskowe) i wykonuje plik jar.
Że env.sh
wygląda to tak,
#!/bin/bash
export FOO="BAR"
export DB_NAME="DATABASE_NAME"
Dodałem printenv
polecenie tylko w celu przetestowania, czy faktycznie działa polecenie źródłowe. Prawdopodobnie powinieneś go usunąć, gdy potwierdzisz, że polecenie źródłowe działa poprawnie lub zmienne środowiskowe pojawią się w dziennikach dokera.
--env-file
argumentu docker run
polecenia. Na przykład jeśli wdrażasz aplikację za pomocą silnika aplikacji Google, a aplikacja działająca w kontenerze wymaga zmiennych środowiskowych ustawionych w kontenerze dokera, nie masz bezpośredniego podejścia do ustawiania zmiennych środowiskowych, ponieważ nie masz kontroli nad docker run
poleceniem . W takim przypadku możesz mieć skrypt, który odszyfrowuje zmienne env przy użyciu powiedzmy KMS, i dodaje je do tych, env.sh
które można uzyskać w celu ustawienia zmiennych env.
.
(kropka) dostępnego regularnie . ( jest taki sam jak )sh
source
source
.
Używając jq do konwersji env na JSON:
env_as_json=`jq -c -n env`
docker run -e HOST_ENV="$env_as_json" <image>
wymaga to jq w wersji 1.6 lub nowszej
to pusta env hosta jako json, zasadniczo tak jak w Dockerfile:
ENV HOST_ENV (all env from the host as json)
docker run -e HOST_ENV="$env_as_json" <image>
? : ? W moim przypadku Docker nie wydaje się rozpoznawać zmiennych lub podpowłok ( ${}
lub $()
), gdy jest przekazywany jako argument dokera . Na przykład: A=123 docker run --rm -it -e HE="$A" ubuntu
następnie wewnątrz tego kontenera: root@947c89c79397:/# echo $HE root@947c89c79397:/#
.... HE
Zmienna tego nie robi.
możemy również hostować zmienną środowiskową komputera za pomocą flagi -e i $:
docker run -it -e MG_HOST=$MG_HOST -e MG_USER=$MG_USER -e MG_PASS=$MG_PASS -e MG_AUTH=$MG_AUTH -e MG_DB=$MG_DB -t image_tag_name_and_version
Korzystając z tej metody, ustaw zmienną env automatycznie z Twoim imieniem w moim przypadku (MG_HOST, MG_USER)
Jeśli używasz Pythona, możesz uzyskać dostęp do tych zmiennych envment wewnątrz dokera
import os
host,username,password,auth,database=os.environ.get('MG_HOST'),os.environ.get('MG_USER'),os.environ.get('MG_PASS'),os.environ.get('MG_AUTH'),os.environ.get('MG_DB')
docker run --rm -it --env-file <(bash -c 'env | grep <your env data>')
Jest sposobem na grepowanie danych przechowywanych w a .env
i przekazywanie ich do Dockera, bez przechowywania danych w sposób niezabezpieczony (więc nie można po prostu patrzeć docker history
i chwytać kluczy.
Załóżmy, że masz mnóstwo AWS .env
:
AWS_ACCESS_KEY: xxxxxxx
AWS_SECRET: xxxxxx
AWS_REGION: xxxxxx
uruchomienie dokera z `` `docker run --rm -it --env-file <(bash -c 'env | grep AWS_') złapie wszystko i przekaże bezpiecznie, aby było dostępne z poziomu kontenera.