Почему точка входа в Docker начинается с sh в запущенном jar?

#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-команды,

  1. Вам нужно проверить, включена ли оболочка в ваш образ, иначе команда завершится ошибкой.
  2. Это может быть проблемой, если вам нужно отправить любой тип сигналов POSIX в контейнер, поскольку /bin/sh он не будет пересылать сигналы дочерним процессам.

Более подробная информация об этом по следующей ссылке, https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd