Подтвердить что ты не робот

Создание динамических переменных среды во время сборки в Docker

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

Я надеялся сделать что-то вроде ENV VAR_NAME $(./script/that/gets/var) в моем файле Docker, но неудивительно, что это не работает (вы просто получаете строку $(./script...).

Я должен упомянуть, что знаю, что docker run --env... сделает это, но я хочу, чтобы он был встроен в контейнер.

Я пропустил что-то очевидное? Возможно ли это?

4b9b3361

Ответ 1

Docker v1.9 или новее

Если вы используете Docker v1.9 или новее, это возможно благодаря поддержке аргументов времени построения. Аргументы объявляются в Dockerfile с использованием инструкции ARG.

ARG REQUIRED_ARGUMENT
ARG OPTIONAL_ARGUMENT=default_value

Когда вы позже создаете свое изображение с помощью docker build, вы можете передавать аргументы с помощью флага --build-arg, как описано в docker docs.

$ docker build --build-arg REQUIRED_ARGUMENT=this-is-required .

Обратите внимание, что рекомендуется не использовать переменные времени сборки для паролей или секретов, таких как ключи или учетные данные.

Кроме того, переменные времени построения могут иметь большое влияние на кеширование. Поэтому Dockerfile должен быть сконструирован с большой осторожностью, чтобы иметь возможность максимально использовать кеширование и ускорять процесс сборки.

Изменить: после ввода leedm777: s answer добавлен "докер более новый, чем v1.9".


Докер перед v1.9

Если вы используете докер-версию до 1.9, подход ARG/--build-arg невозможен. Вы не могли разрешить эту информацию во время сборки, поэтому вам пришлось передать их в качестве параметров команде docker run.

Изображения Docker должны быть последовательными с течением времени, тогда как контейнеры могут быть изменены и рассматриваться как "отбрасывающие процессы".

Старое решение этой проблемы заключалось в использовании шаблонов. Это не аккуратное решение, но в то время было одним из немногих жизнеспособных вариантов. (Вдохновение от это обсуждение).

  • сохранить все ваши динамические данные в файле json или yaml
  • создать шаблон шаблона docker, в котором динамическая версия может быть впоследствии расширена.
  • напишите script, который создает файл Docker из данных конфигурации, используя некоторую библиотеку шаблонов, с которой вы знакомы с

Ответ 2

Docker 1.9 добавила поддержку аргументов времени построения.

В Dockerfile вы добавьте оператор ARG, который имеет аналогичный синтаксис ENV.

ARG FOO_REQUIRED
ARG BAR_OPTIONAL=something

Во время сборки вы можете передать передать аргумент --build-arg для установки аргумента для этой сборки. Любые ARG, которые не были заданы по умолчанию в Dockerfile, должны быть указаны.

$ docker build --build-arg FOO_REQUIRED=best-foo-ever .

Ответ 3

Чтобы построить ENV VAR_NAME $(./script/that/gets/var) в контейнер, создайте динамический файл Docker во время сборки:

$ docker build -t awesome -f Dockerfile .
$ # get VAR_NAME value: 
$ VAR_VALUE=`docker run --rm awesome \
    bash -c 'echo $(./script/that/gets/var)'`
$ # use dynamic Dockerfile:
$ {
     echo "FROM awesome"
     echo "ENV VAR_NAME $VAR_VALUE"
   } | docker build -t awesome -

https://github.com/42ua/docker-autobuild/blob/master/emscripten-sdk/README.md#build-docker-image