Как передать переменные среды в контейнеры Docker?

Я новичок в Docker, и неясно, как получить доступ к внешней базе данных из контейнера. Является лучшим способом жесткого кода в строке подключения?

# Dockerfile
ENV DATABASE_URL amazon:rds/connection?string

Ответ 1

Вы можете передавать переменные среды в свои контейнеры с флагом -e.

Пример из запуска script:

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. Строки комментариев должны иметь только префикС#

Ответ 2

Вы можете передать с -e параметров -e с помощью команды docker run.. как упомянуто здесь и как указано @errata.
Однако возможный недостаток этого подхода заключается в том, что ваши учетные данные будут отображаться в списке процессов, где вы его запускаете.
Чтобы сделать его более безопасным, вы можете записать свои учетные данные в файле конфигурации и docker run с --env-file как указано здесь. Затем вы можете контролировать доступ к этому файлу конфигурации, чтобы другие, имеющие доступ к этому компьютеру, не увидели ваши учетные данные.

Ответ 3

Если вы используете "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"

Надеюсь, это поможет вам избежать жесткого кодирования строки подключения к базе данных в любом файле в вашем контейнере!

Ответ 4

Используйте -e или - -e значение nv для установки переменных среды (по умолчанию []).

Пример из сценария запуска:

 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/

Ответ 5

Используя docker-compose, приведенный ниже пример показывает, как вы можете наследовать переменные оболочки env как в файле docker-compose.yml, так и в любом файле Docker, который вызывается docker-compose для создания изображений. Я нашел это полезным, если сказать в команде Dockerfile RUN мне нужно выполнить команды, специфичные для среды.

(ваша оболочка имеет RAILS_ENV=development уже существующую в среде)

Докер-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

Ответ 6

Есть хороший способ, как передать переменные окружения хост-машины в докер-контейнер:

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

Используйте эту технику очень осторожно, потому что env > env_file ВСЕ переменные ENV хост-машины в env_file и сделает их доступными в работающем контейнере.

Ответ 8

Другой способ - использовать полномочия /usr/bin/env:

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

Ответ 9

Если у вас есть переменные окружения в 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 только для проверки работы реальной команды источника. Вероятно, вы должны удалить его, когда подтвердите, что команда источника работает нормально, или переменные окружения появятся в ваших журналах докеров.

Ответ 10

Используя 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)