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

Dockerfile - установить ENV в результате команды

Можно ли установить переменную ENK докера для результата команды? Как:

ENV MY_VAR whoami

Я хочу, чтобы MY_VAR получил значение "root" или что-то еще whoami возвращает

4b9b3361

Ответ 1

В дополнение к ответу DarkSideF.

Вы должны знать, что каждая строка/команда в Dockerfile запускается в другом контейнере.

Вы можете сделать что-то вроде этого:

RUN export bleah=$(hostname -f);echo $bleah;

Это выполняется в одном контейнере.

Ответ 2

У меня была такая же проблема и нашла способ установить переменную среды в результате функции с помощью команды RUN в файле docker.

Например, мне нужно установить SECRET_KEY_BASE для приложения Rails только один раз без изменения, как при запуске:

docker run  -e SECRET_KEY_BASE="$(openssl rand -hex 64)"

Вместо этого я пишу строку Dockerfile, например:

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'

и моя переменная env, доступная от root, даже после входа bash. или может быть

RUN /bin/bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" > /etc/profile.d/docker_init.sh'

то эта переменная доступна в командах CMD и ENTRYPOINT

Docker кэширует его как слой и меняет его, только если вы измените некоторые строки перед ним.

Вы также можете попробовать различные способы установить переменную среды.

Ответ 3

В это время результат команды можно использовать с RUN export, но не может быть назначен переменной ENV.

Известная проблема: https://github.com/docker/docker/issues/29110

Ответ 4

Этот ответ является ответом на @DarkSideF,

Метод, который он предлагает, следующий в Dockerfile:

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'

(добавление экспорта в /etc/bash.bashrc)

Это хорошо, но переменная окружения будет доступна только для процесса /bin/bash, и если вы попытаетесь запустить приложение-докер, например приложение Node.js, /etc/bash.bashrc будет полностью проигнорировано, и ваше приложение выиграет У вас нет единого ключа, что SECRET_KEY_BASE при попытке доступа к process.env.SECRET_KEY_BASE.

Вот почему ключевое слово ENV - это то, что каждый пытается использовать с динамической командой, потому что каждый раз, когда вы запускаете свой контейнер или используете команду exec, Docker проверяет ENV и обрабатывает каждое значение в текущем запуске (подобно -e).

Одним из решений является использование обертки (кредит для @duglin в этой проблеме github). Имейте файл оболочки (например, envwrapper) в корне вашего проекта, содержащий:

#!/bin/bash
export SECRET_KEY_BASE="$(openssl rand -hex 64)"
export ANOTHER_ENV "hello world"
$*

а затем в Dockerfile:

...
COPY . .
RUN mv envwrapper /bin/.
RUN chmod 755 /bin/envwrapper
CMD envwrapper myapp

Ответ 5

В качестве дополнения к ответу @DarkSideF, если вы хотите повторно использовать результат предыдущей команды в Dockerfile во время процесса сборки, вы можете использовать следующее обходное решение:

  1. запустить команду, сохранить результат в файле
  2. используйте подстановку команд, чтобы получить предыдущий результат из этого файла в другую команду

Например:

RUN echo "bla" > ./result
RUN echo $(cat ./result)

Для чего-то более чистого, вы также можете использовать следующий gist, который предоставляет небольшую CLI под названием envstore.py:

RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)

Или вы можете использовать библиотеку python-dotenv, которая имеет аналогичный CLI.

Ответ 6

Не уверен, что это то, что вы искали, но для того, чтобы вставить ENV vars или ARGS в вашу сборку .Dockerfile, этот шаблон работает.

в вашем my_build.sh:

echo getting version of osbase image to build from
OSBASE=$(grep "osbase_version" .version | sed 's/^.*: //')

echo building docker
docker build -f \
--build-arg ARTIFACT_TAG=$OSBASE \
PATH_TO_MY.Dockerfile \
-t my_artifact_home_url/bucketname:$TAG .

для получения ARG в вашем .Dockerfile фрагмент может выглядеть так:

FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}

В качестве альтернативы для получения ENV в вашем .Dockerfile фрагмент может выглядеть следующим образом:

FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}

идея заключается в том, что вы запускаете скрипт оболочки, и он вызывает .Dockerfile с аргументами, передаваемыми в качестве параметров сборки.