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