Как использовать переменную среды Docker в массиве ENTRYPOINT?

109

Если, скажем ENV ADDRESSEE=world, я устанавливаю переменную среды и хочу использовать ее в сценарии точки входа, объединенной в фиксированную строку, например:

ENTRYPOINT ["./greeting", "--message", "Hello, world!"]

с worldизменчивой ценностью окружающей среды, как мне это сделать? Я пробовал использовать, "Hello, $ADDRESSEE"но, похоже, это не сработало, потому что нужно $ADDRESSEEпонимать буквально.

Психологический удар
источник

Ответы:

217

Вы используете exec-форму ENTRYPOINT. В отличие от формы оболочки , то Exec форма не вызывает командную оболочку. Это означает, что нормальной обработки оболочки не происходит. Например, ENTRYPOINT [ "echo", "$HOME" ]не будет выполнять подстановку переменных в $ HOME. Если вы хотите оболочки обработки затем либо использовать форму оболочки или выполнить оболочку непосредственно, например: ENTRYPOINT [ "sh", "-c", "echo $HOME" ].
При использовании формы exec и непосредственном выполнении оболочки, как и в случае формы оболочки, расширение переменной среды выполняется оболочкой, а не docker. ( Из справочника Dockerfile )

В вашем случае я бы использовал форму оболочки

ENTRYPOINT ./greeting --message "Hello, $ADDRESSEE\!"
витр
источник
2
ENTRYPOINT java -jar /dockertest.jar -Djava.security.egd=file:/dev/./urandom -Dserver.port=$portпока ENV port=123. ENV порта не разрешен. Есть идеи, почему?
xetra11
1
Хотя это работает, похоже, что это создает некоторые новые проблемы, такие как отсутствие переданных аргументов в эту точку входа. Например, вы не можете добавить --attitude "shouting"аргумент к docker runкоманде, которая должна быть передана./greeting
Дэниел Ф,
5
Используйте, ENTRYPOINT ./greeting --message "Hello, $ADDRESSEE\! $0 $@"если вы также хотите передать дополнительные переменные ./greetingчерез docker runвызов (или передать CMDфайл Dockerfile)
Daniel F
3
Обратите внимание, что форма оболочки может привести к тому, что сигналы не будут переданы процессу ( greetingв вашем примере). hynek.me/articles/docker-signals
jbg
могу ли я получить значение переменной среды в форме exec, например `[myexecutable.sh,« $ variable »], я могу сделать это с помощью [« sh »,« -c »,« echo $ var »], но не таким образом
Лазарь
13

Я попытался решить с помощью предложенного ответа, но все равно столкнулся с некоторыми проблемами ...

Это было решение моей проблемы:

ARG APP_EXE="AppName.exe"
ENV _EXE=${APP_EXE}

# Build a shell script because the ENTRYPOINT command doesn't like using ENV
RUN echo "#!/bin/bash \n mono ${_EXE}" > ./entrypoint.sh
RUN chmod +x ./entrypoint.sh

# Run the generated shell script.
ENTRYPOINT ["./entrypoint.sh"]

Конкретно нацелившись на вашу проблему:

RUN echo "#!/bin/bash \n ./greeting --message ${ADDRESSEE}" > ./entrypoint.sh
RUN chmod +x ./entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]
Бен Кауфман
источник
похоже, ваш ответ не дает полных решений вопроса OP
user9405863
Я полагаю, я не понимаю, как он не дает решения вопроса OP ... Я обновил пример, чтобы решить точный вопрос.
Бен Кауфман
Вы упомянули, что все еще столкнулись с некоторыми проблемами !!
user9405863
правильно, поэтому я представил новое решение. ... "принятый" ответ не сработал для меня, поэтому я повторил сценарий оболочки, и это сработало.
Ben Kauffman
2
Мне было бы интересно услышать ваш подход тогда @ReverendTim;)
Бен Кауфман
6

После долгой боли и огромной помощи @vitr et al. Я решил попробовать

  • стандартная замена bash
  • Оболочка формы из Entrypoint (большой наконечник сверху)

и это сработало.

ENV LISTEN_PORT=""

ENTRYPOINT java -cp "app:app/lib/*" hello.Application --server.port=${LISTEN_PORT:-80}

например

docker run --rm -p 8080:8080 -d --env LISTEN_PORT=8080 my-image

и

docker run --rm -p 8080:80 -d my-image

оба правильно установили порт в моем контейнере

Ссылки

см. https://www.cyberciti.biz/tips/bash-shell-parameter-substitution-2.html

mlo55
источник