Чи можна встановити змінну ENV докера на результат команди? Люблю:
ENV MY_VAR whoami
я хочу, щоб MY_VAR отримав значення "root" або те, що повертає хтомі
Відповіді:
Як доповнення до відповіді DarkSideF.
Вам слід пам’ятати, що кожен рядок / команда в Dockerfile запускається в іншому контейнері.
Ви можете зробити щось подібне:
RUN export bleah=$(hostname -f);echo $bleah;
Це виконується в одному контейнері.
$bleah
це НЕ доступні в будь-якому місці за межами цієї команди RUN, навіть не на наступному рядку в тому ж dockerfile, НЕ кажучи вже про інше зображенні він заснований геть. Тут справді очевидна відсутність функції докера, схоже, запис і читання з файлу - це єдиний спосіб насправді зберігати (динамічні) змінні у зображеннях і передавати їх між зображеннями, що здається надзвичайно хакерським.
У мене була та ж проблема, і я знайшов спосіб встановити змінну середовища в результаті функції за допомогою команди 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 кешує його як шар і змінює лише в тому випадку, якщо ви змінили кілька рядків перед ним.
Ви також можете спробувати різні способи встановлення змінної середовища.
*.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
).
Одним із рішень є використання обгортки ( в цьому випуску github належить @duglin ). Розмістіть файл обгортки (наприклад ) у корені проекту, що містить: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, яка має подібний CLI.
Не впевнений, що це те, що ви шукали, але для того, щоб ввести 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}
ідея полягає в тому, що ви запускаєте скрипт оболонки, і він викликає файл .Docker з аргументами, переданими як параметри побудови.