#docker #dockerfile
#docker #dockerfile
Вопрос:
Почему эта точка входа использует sh при запуске jar? ENTRYPOINT ["sh", "-c", "java -jar app.jar"]
. В чем будет его разница при простом использовании ENTRYPOINT ["java", "-jar", "app.jar"]
?
Ответ №1:
ENTRYPOINT
Директива (наряду с CMD
and RUN
) имеет две формы. Если вы используете синтаксис JSON-array, тогда нет интерпретации, разделения слов или какой-либо другой обработки; то, что вы передаете, — это именно то, что запускается.
# Three words
ENTRYPOINT ["java", "-jar", "app.jar"]
# You're already quoting things so spaces stay as part of each word
ENTRYPOINT ["java", "-jar", "my app.jar"]
# There is no interpolation so variable names do not get expanded --
# this looks for a file literally named `$JARFILE`
ENTRYPOINT ["java", "-jar", "$JARFILE"]
# There is only one command-line option with embedded spaces
ENTRYPOINT ["java", "-jar", "app.jar", "-a -b -c"]
В нескольких случаях (особенно при расширении переменной) вам действительно нужна оболочка для запуска. Вот тут sh -c
-то и возникает. Он принимает одно слово и обрабатывает его как команду оболочки. Затем (в основном) игнорируются все остальные параметры, что означает CMD
, что фактически игнорируется.
# This expands the environment variable `$JARFILE`, but if
# you pass additional options in `CMD`, they're lost
ENTRYPOINT ["sh", "-c", "java -jar $JARFILE"]
Однако на самом деле вы не должны использовать этот синтаксис, потому что Docker предоставляет синтаксис простой строки, который автоматически вставляется sh -c
для вас.
# Exactly the same as above
ENTRYPOINT java -jar $JARFILE
# Three additional command-line options, since the shell does splitting
ENTRYPOINT java -jar app.jar -a -b -c
Помните, что Docker объединит ENTRYPOINT
и CMD
в одну команду. Это может привести к шаблону «контейнер как команда», но вы должны использовать форму JSON-массива ENTRYPOINT
, и у нее не должно быть sh -c
оболочки.
ENTRYPOINT ["java", "-jar", "app.jar"]
CMD ["-a", "-b", "-c"]
(Также помните, что CMD
это намного проще переопределить в docker run
команде, и есть полезный шаблон использования ENTRYPOINT
в качестве сценария-оболочки для выполнения первоначальной настройки, а затем выполнения в CMD
качестве основного процесса контейнера. Для простых команд, подобных тому, что вы показываете, вы можете предпочесть CMD
.)
Ответ №2:
Вызов оболочки для выполнения вашей Java-команды,
- Вам нужно проверить, включена ли оболочка в ваш образ, иначе команда завершится ошибкой.
- Это может быть проблемой, если вам нужно отправить любой тип сигналов POSIX в контейнер, поскольку
/bin/sh
он не будет пересылать сигналы дочерним процессам.
Более подробная информация об этом по следующей ссылке, https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd