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


Відповіді:


23

Як доповнення до відповіді DarkSideF.

Вам слід пам’ятати, що кожен рядок / команда в Dockerfile запускається в іншому контейнері.

Ви можете зробити щось подібне:

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

Це виконується в одному контейнері.


14
Просто щоб прояснити - $bleahце НЕ доступні в будь-якому місці за межами цієї команди RUN, навіть не на наступному рядку в тому ж dockerfile, НЕ кажучи вже про інше зображенні він заснований геть. Тут справді очевидна відсутність функції докера, схоже, запис і читання з файлу - це єдиний спосіб насправді зберігати (динамічні) змінні у зображеннях і передавати їх між зображеннями, що здається надзвичайно хакерським.
davnicwil

17

У мене була та ж проблема, і я знайшов спосіб встановити змінну середовища в результаті функції за допомогою команди 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 кешує його як шар і змінює лише в тому випадку, якщо ви змінили кілька рядків перед ним.

Ви також можете спробувати різні способи встановлення змінної середовища.


/Etc/profile.d/docker_init.sh все-таки щось? Ця відповідь - це єдина згадка про неї, яку я можу знайти в Google, і вона для мене не працює. Чи це, можливо, було частиною механізму виконання Docker у 2016 році, який вже не діє?
SigmaX

1
@SigmaX Це не докер, це швидше справа в Linux . Будь-який *.shфайл, що /etc/profile.d/знаходиться всередині , використовується для заповнення середовища
Мадаколь,


7

Ця відповідь є відповіддю на @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

2

Як доповнення до відповіді @ DarkSideF, якщо ви хочете повторно використати результат попередньої команди у своєму Dockerfile в процесі побудови , ви можете використати таке обхідне рішення:

  1. запустити команду, зберегти результат у файлі
  2. використовуйте заміну команди, щоб отримати попередній результат із цього файлу в іншу команду

Наприклад :

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.


2

Не впевнений, що це те, що ви шукали, але для того, щоб ввести 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 з аргументами, переданими як параметри побудови.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.