Ответы:
Вы можете передавать переменные окружения в ваши контейнеры с -e
флагом.
Пример из скрипта запуска:
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
Или, если вы не хотите иметь значение в командной строке, где оно будет отображаться и ps
т. Д., -e
Можете получить значение из текущей среды, если вы просто передадите его без =
:
sudo PASSWORD='foo' docker run [...] -e PASSWORD [...]
Если у вас много переменных окружения и особенно если они предназначены для секретности, вы можете использовать env-файл :
$ docker run --env-file ./env.list ubuntu bash
Флаг --env-file принимает имя файла в качестве аргумента и ожидает, что каждая строка будет в формате VAR = VAL, имитируя аргумент, передаваемый --env. Строки комментариев должны быть только с префиксом #
export PASSWORD=foo
вместо этого, и переменная будет передана docker run
как переменная окружения, заставляя docker run -e PASSWORD
работать.
Вы можете передать используя -e
параметры с docker run ..
командой, как упомянуто здесь и как упомянуто @errata.
Однако возможный недостаток этого подхода заключается в том, что ваши учетные данные будут отображаться в списке процессов, где вы его запускаете.
Для того, чтобы сделать его более безопасным, вы можете написать свои учетные данные в файле конфигурации и делать docker run
с , --env-file
как указано здесь . Затем вы можете контролировать доступ к этому файлу конфигурации, чтобы другие, имеющие доступ к этому компьютеру, не увидели ваши учетные данные.
--env-file
, когда вы используете --env
ваши значения env, они будут заключены в кавычки / экранированы со стандартной семантикой любой используемой вами оболочки, но при использовании --env-file
значений, которые вы получите внутри вашего контейнера, все будет иначе. Команда docker run просто читает файл, выполняет базовый анализ и передает значения в контейнер, это не эквивалентно поведению вашей оболочки. Просто небольшая ошибка, которую нужно знать, если вы конвертируете кучу --env
записей в --env-file
.
Если вы используете 'docker-compose' в качестве метода ускорения ваших контейнеров, на самом деле есть полезный способ передать переменную среды, определенную на вашем сервере, в контейнер Docker.
docker-compose.yml
Допустим, в вашем файле вы раскручиваете базовый контейнер hapi-js, а код выглядит так:
hapi_server:
container_name: hapi_server
image: node_image
expose:
- "3000"
Предположим, что на локальном сервере, на котором находится ваш проект Docker, есть переменная среды с именем 'NODE_DB_CONNECT', которую вы хотите передать в свой контейнер hapi-js, и вы хотите, чтобы его новое имя было 'HAPI_DB_CONNECT'. Затем в docker-compose.yml
файле вы передадите локальную переменную среды в контейнер и переименуете ее так:
hapi_server:
container_name: hapi_server
image: node_image
environment:
- HAPI_DB_CONNECT=${NODE_DB_CONNECT}
expose:
- "3000"
Я надеюсь, что это поможет вам избежать жесткого кодирования строки подключения к базе данных в любом файле вашего контейнера!
Используя docker-compose
, вы можете наследовать переменные env в docker-compose.yml и впоследствии любые Dockerfile (ы), вызываемые docker-compose
для создания образов. Это полезно, когда Dockerfile
RUN
команда должна выполнять команды, специфичные для среды.
(ваша оболочка RAILS_ENV=development
уже существует в среде)
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
Таким образом , я не нужно указывать переменные окружения в файлах или docker-compose
build
/ up
команд:
docker-compose build
docker-compose up
Используйте -e
значение или --env для установки переменных среды (по умолчанию []).
Пример из скрипта запуска:
docker run -e myhost='localhost' -it busybox sh
Если вы хотите использовать несколько сред из командной строки, то перед каждой переменной среды используйте -e
флаг.
Пример:
sudo docker run -d -t -i -e NAMESPACE='staging' -e PASSWORD='foo' busybox sh
Примечание: убедитесь, что имя контейнера указано после переменной окружения, а не до этого.
Если вам нужно установить много переменных, используйте --env-file
флаг
Например,
$ docker run --env-file ./my_env ubuntu bash
Для любой другой помощи, посмотрите в справку Docker:
$ docker run --help
Официальная документация: https://docs.docker.com/compose/environment-variables/
ubuntu bash
? Это относится к изображениям, созданным с Ubuntu в качестве базового изображения, или к каждому изображению?
-e
аргументов давным-давно! Я даже не могу понять, почему они сделали это необходимым ...
Есть хороший способ, как передать переменные окружения хост-машины в докер-контейнер:
env > env_file && docker run --env-file env_file image_name
Используйте эту технику очень осторожно, потому
env > env_file
что в нее будут помещены ВСЕ переменные ENV хост-машиныenv_file
и они будут доступны в работающем контейнере.
Для Amazon AWS ECS / ECR вы должны управлять переменными среды ( особенно секретами ) с помощью частного сегмента S3. См. Сообщение в блоге « Как управлять секретами для приложений на основе сервисов контейнеров Amazon EC2 с помощью Amazon S3 и Docker» .
Если у вас есть переменные окружения env.sh
локально и вы хотите установить их при запуске контейнера, вы можете попробовать
COPY env.sh /env.sh
COPY <filename>.jar /<filename>.jar
ENTRYPOINT ["/bin/bash" , "-c", "source /env.sh && printenv && java -jar /<filename>.jar"]
Эта команда запускает контейнер с оболочкой bash (я хочу оболочку bash, поскольку source
это команда bash), получает исходный env.sh
файл (который устанавливает переменные окружения) и выполняет файл jar.
На env.sh
внешнем виде , как это,
#!/bin/bash
export FOO="BAR"
export DB_NAME="DATABASE_NAME"
Я добавил printenv
команду только для проверки того, что фактическая команда источника работает. Вы, вероятно, должны удалить его, когда подтвердите, что команда источника работает нормально, или переменные окружения появятся в ваших журналах докера.
--env-file
arg для docker run
команды. Например, если вы развертываете приложение с использованием механизма приложений Google, а приложению, работающему внутри контейнера, требуются переменные среды, установленные внутри контейнера Docker, у вас нет прямого подхода для установки переменных среды, поскольку вы не можете контролировать docker run
команду , В таком случае у вас может быть сценарий, который расшифровывает переменные env с помощью, скажем, KMS и добавляет их к тому, env.sh
который можно получить для установки переменных env.
.
(точка), доступную в обычном, sh
вместо source
. (так source
же, как .
)
Используя jq для конвертации env в JSON:
env_as_json=`jq -c -n env`
docker run -e HOST_ENV="$env_as_json" <image>
это требует JQ версии 1.6 или новее
это pust хост env как json, по сути, так в Dockerfile:
ENV HOST_ENV (all env from the host as json)
docker run -e HOST_ENV="$env_as_json" <image>
? : ? В моем случае Docker, по-видимому, не разрешает переменные или подоболочки ( ${}
или $()
) при передаче в качестве аргументов docker. Например: A=123 docker run --rm -it -e HE="$A" ubuntu
затем внутри этого контейнера: root@947c89c79397:/# echo $HE root@947c89c79397:/#
.... HE
Переменная не делает это.
мы также можем разместить переменную окружения компьютера, используя флаг -e и $:
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
Используя этот метод, установите переменную env автоматически с вашим именем в моем случае (MG_HOST, MG_USER)
Если вы используете python, вы можете получить доступ к этим переменным envment в Docker с помощью
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>')
Это способ получить данные, хранящиеся в a, .env
и передать их в Docker, при этом ничего не хранится небезопасно (так что вы не можете просто смотреть docker history
и брать ключи).
Скажем, у вас есть куча вещей от AWS, .env
вот так:
AWS_ACCESS_KEY: xxxxxxx
AWS_SECRET: xxxxxx
AWS_REGION: xxxxxx
запуск docker с `` `docker run --rm -it --env-file <(bash -c 'env | grep AWS_') соберет все это и безопасно передаст, чтобы получить доступ из контейнера.