[英]Dockerfile - exec form of ENTRYPOINT and shell form of CMD
I am looking at Docker's documentation to understand what would be behavior of ENTRYPOINT
defined in exec form and CMD
defined in shell form.我正在查看 Docker 的文档,以了解以 exec 形式定义的 ENTRYPOINT 和以
CMD
形式定义的ENTRYPOINT
的行为。
The example in the docs only shows something like exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
which does not tell me anything.文档中的示例仅显示类似
exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
的内容,但没有告诉我任何信息。
For example, what if we had:例如,如果我们有:
ENV JAVA_OPTS '-XX:+UseG1GC -Xms512m -Xmx1536m'
ENTRYPOINT ["java"]
CMD $JAVA_OPTS -jar app.jar
Would the problem with signal propagation exist here (in other words, would any extra subshell be spawned here)?信号传播的问题是否存在于此(换句话说,是否会在此处生成任何额外的子外壳)?
ENTRYPOINT
or CMD
are not JSON arrays, they are interpreted as strings and converted to a length-3 array ["/bin/sh", "-c", "..."]
.ENTRYPOINT
或CMD
不是 JSON arrays,它们将被解释为字符串并转换为长度为 3 的数组["/bin/sh", "-c", "..."]
。 So in your example, the final command list would be所以在你的例子中,最终的命令列表是
["java", "/bin/sh", "-c", "$JAVA_OPTS -jar app.jar"]
or in Bourne shell syntax或 Bourne shell 语法
java /bin/sh -c '$JAVA_OPTS -jar app.jar'
This passes the shell interpreter /bin/sh
as an argument to java
;这将 shell 解释器
/bin/sh
作为参数传递给java
; that almost certainly is not what you intend.这几乎肯定不是你想要的。
If the CMD
is anything other than a complete command, it must use the JSON-array syntax, which in turn means it can't use any shell features and it can't expand environment variable references.如果
CMD
不是完整的命令,它必须使用 JSON 数组语法,这反过来意味着它不能使用任何 shell 功能,也不能扩展环境变量引用。 This would include both the "container-as-command" pattern where ENTRYPOINT
is the command to run and CMD
its arguments, and the antipattern you show here where ENTRYPOINT
is the interpreter only (and you have to repeat the -jar app.jar
option in a docker run
command override).这将包括“容器作为命令”模式,其中
ENTRYPOINT
是要运行的命令和CMD
它的 arguments,以及您在此处显示的反模式,其中ENTRYPOINT
仅是解释器(并且您必须重复-jar app.jar
选项在docker run
命令覆盖中)。
I prefer a setup where CMD
is always a complete shell command.我更喜欢
CMD
始终是完整的 shell 命令的设置。 If you have an ENTRYPOINT
at all, it's a script that does some startup-time setup and then runs exec "$@"
to run the command passed as arguments. This can accept either form of CMD
.如果您有一个
ENTRYPOINT
,它是一个脚本,它执行一些启动时设置,然后运行exec "$@"
以运行作为 arguments 传递的命令。这可以接受CMD
的任何一种形式。
# ENTRYPOINT ["./docker-entrypoint.sh"] # optional
CMD java $JAVA_OPTS -jar app.jar # in a single shell-format CMD
It took me a while but I finally figured out what is the point of /bin/sh -c
in this use-case.我花了一段时间,但我终于弄清楚
/bin/sh -c
在这个用例中的意义是什么。 We can for example use tini as an entrypoint例如,我们可以使用tini作为入口点
ENTRYPOINT ["tini", "--"]
and then a shell for of CMD, but we need to use exec
in order to replace a subshell, that is然后是 CMD 的 shell,但是我们需要使用
exec
来替换子 shell,即
CMD exec java $JAVA_OPTS -jar app.jar
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.