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

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

# Dockerfile
ENV DATABASE_URL amazon:rds/connection?string

8 ответов


вы можете передавать переменные среды в контейнеры с помощью -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, etc., -e может вытащить значение из текущей среды, если вы просто дадите его без =:

sudo PASSWORD='foo' docker run  [...] -e PASSWORD [...]

если у вас есть много переменных среды, и особенно если они должны быть секретными, вы можете используйте env-файл:

$ docker run --env-file ./env.list ubuntu bash

флаг --env-file принимает имя файла в качестве аргумента и ожидает, что каждая строка будет в формате VAR=VAL, имитируя аргумент, переданный в --env. Строки комментариев должны начинаться с #


вы можете пройти через -e параметры с как уже упоминалось здесь и, как упоминалось в @errata.
Однако возможным недостатком этого подхода является то, что ваши учетные данные будут отображаться в списке процессов, где вы их запускаете.
Чтобы сделать его более безопасным, вы можете написать свои данные в файл конфигурации и сделать docker run С --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"

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


использовать -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 run --help

официальной документации: https://docs.docker.com/compose/environment-variables/


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

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

докер-сочинять.в формате 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

для Amazon AWS ECS / ECR необходимо управлять переменными среды (особенно секреты) через частное ведро S3. Смотрите блог как управлять секретами для приложений на основе контейнерных сервисов Amazon EC2 с помощью Amazon S3 и Docker.


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

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

если у вас есть переменные окружения в 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 file (который устанавливает переменные среды) и выполняет файл jar.

на env.sh выглядит так,

#!/bin/bash
export FOO="BAR"
export DB_NAME="DATABASE_NAME"

добавил printenv команда только для проверки этого фактического команда источника работает. Вероятно, вы должны удалить его, когда подтвердите, что команда source работает нормально, или переменные среды появятся в журналах docker.