首页 > 解决方案 > Why does the entrypoint in Docker starts with sh in running jar?

问题描述

Why does this entrypoint uses sh in running the jar? ENTRYPOINT ["sh", "-c", "java -jar app.jar"]. What would be its difference in just using ENTRYPOINT ["java", "-jar", "app.jar"]?

标签: dockerdockerfile

解决方案


ENTRYPOINT指令(与 CMDand一起RUN)有两种形式。如果您使用JSON 数组语法,则没有解释、分词或任何其他处理;你传入的正是运行的内容。

# 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"]

在某些情况下(尤其是变量扩展),您确实需要一个 shell 来运行。这就是sh -c进来的地方。它需要一个单词并将其作为 shell 命令处理。然后它(大部分)忽略所有其他选项,这意味着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 会将and组合成一个命令ENTRYPOINTCMD。这可能导致“容器即命令”模式,但您必须使用 JSON 数组形式ENTRYPOINT,并且它不能sh -c包装器。

ENTRYPOINT ["java", "-jar", "app.jar"]
CMD ["-a", "-b", "-c"]

(还请记住,CMD在命令中覆盖要容易得多docker run,并且有一种有用的模式,即使用ENTRYPOINT包装脚本进行首次设置,然后CMD作为主容器进程执行。对于像您展示的简单命令,您可能更喜欢CMD。)


推荐阅读