Можно ли установить переменную ENV для докеров в результате выполнения команды? Подобно:
ENV MY_VAR whoami
я хочу, чтобы MY_VAR получил значение "root" или что-то еще, что возвращает whoami
Ответы:
Как дополнение к DarkSideF ответ.
Вы должны знать, что каждая строка / команда в Dockerfile запускается в другом контейнере.
Вы можете сделать что-то вроде этого:
RUN export bleah=$(hostname -f);echo $bleah;
Это выполняется в одном контейнере.
$bleah
это не доступны в любом месте за пределами этой команды RUN, даже не на следующей строке в том же dockerfile, не говоря уже о другом изображении он основан прочь. Здесь действительно очевидная отсутствующая функция в докере, похоже, что запись и чтение из файла - это единственный способ на самом деле хранить (динамические) переменные в изображениях и передавать их между изображениями, что кажется супер хакерским.
У меня была такая же проблема, и я нашел способ установить переменную среды как результат функции с помощью команды RUN в файле dockerfile.
Например, мне нужно установить 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 кеширует его как слой и изменяет только если вы измените некоторые строки перед ним.
Вы также можете попробовать разные способы установки переменной окружения.
*.sh
файл внутри /etc/profile.d/
используется для заполнения среды
В настоящее время результат команды можно использовать с переменной RUN export
, но нельзя присвоить ей ENV
.
Известная проблема: https://github.com/docker/docker/issues/29110
Этот ответ является ответом на @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
В дополнение к ответу @ DarkSideF, если вы хотите повторно использовать результат предыдущей команды в своем Dockerfile
во время процесса сборки , вы можете использовать следующий обходной путь:
Например :
RUN echo "bla" > ./result
RUN echo $(cat ./result)
Для чего-то более чистого вы также можете использовать следующую суть, которая предоставляет небольшой CLI с именем envstore.py
:
RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)
Или вы можете использовать библиотеку python-dotenv с аналогичным интерфейсом командной строки.
Не уверен, что это то, что вы искали, но для внедрения переменных ENV или 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 с аргументами, переданными в качестве параметров сборки.