Відповіді:
Ви можете передати змінні середовища у ваші контейнери із -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-файлу приймає ім'я файлу як аргумент і очікує, що кожен рядок буде у форматі 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
значень, які ви отримаєте всередині вашого контейнера, будуть іншими. Команда run docker просто зчитує файл, робить дуже основний аналіз і передає значення в контейнер, це не еквівалентно тому, як поводиться ваша оболонка. Лише невеликий готч, про який слід знати, перетворюючи купу --env
записів у --env-file
.
Якщо ви використовуєте "docker-compose" в якості методу для спінації ваших контейнерів, насправді є корисним способом передавання змінної середовища, визначеної на вашому сервері, до контейнера Docker.
docker-compose.yml
Скажімо, у вашому файлі ви створюєте базовий контейнер hapi-js, і код виглядає так:
hapi_server:
container_name: hapi_server
image: node_image
expose:
- "3000"
Скажімо, що локальний сервер, на якому працює ваш проект докера, має змінну середовища з назвою "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 (s), викликаний 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}
Докерфайл :
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 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 shell, оскільки 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 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 або новіша
це пустить хост env як json, по суті, як у Dockerfile:
ENV HOST_ENV (all env from the host as json)
docker run -e HOST_ENV="$env_as_json" <image>
? : ? У моєму випадку 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_') захопить це все і передасть його надійно, щоб бути доступним зсередини контейнера.