![](/img/trans.png)
[英]Dockerfile ENTRYPOINT EXEC form not working with Powershell
[英]Dockerfile - exec form of ENTRYPOINT and shell form of CMD
我正在查看 Docker 的文档,以了解以 exec 形式定义的 ENTRYPOINT 和以CMD
形式定义的ENTRYPOINT
的行为。
文档中的示例仅显示类似exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
的内容,但没有告诉我任何信息。
例如,如果我们有:
ENV JAVA_OPTS '-XX:+UseG1GC -Xms512m -Xmx1536m'
ENTRYPOINT ["java"]
CMD $JAVA_OPTS -jar app.jar
信号传播的问题是否存在于此(换句话说,是否会在此处生成任何额外的子外壳)?
ENTRYPOINT
或CMD
不是 JSON arrays,它们将被解释为字符串并转换为长度为 3 的数组["/bin/sh", "-c", "..."]
。所以在你的例子中,最终的命令列表是
["java", "/bin/sh", "-c", "$JAVA_OPTS -jar app.jar"]
或 Bourne shell 语法
java /bin/sh -c '$JAVA_OPTS -jar app.jar'
这将 shell 解释器/bin/sh
作为参数传递给java
; 这几乎肯定不是你想要的。
如果CMD
不是完整的命令,它必须使用 JSON 数组语法,这反过来意味着它不能使用任何 shell 功能,也不能扩展环境变量引用。 这将包括“容器作为命令”模式,其中ENTRYPOINT
是要运行的命令和CMD
它的 arguments,以及您在此处显示的反模式,其中ENTRYPOINT
仅是解释器(并且您必须重复-jar app.jar
选项在docker run
命令覆盖中)。
我更喜欢CMD
始终是完整的 shell 命令的设置。 如果您有一个ENTRYPOINT
,它是一个脚本,它执行一些启动时设置,然后运行exec "$@"
以运行作为 arguments 传递的命令。这可以接受CMD
的任何一种形式。
# ENTRYPOINT ["./docker-entrypoint.sh"] # optional
CMD java $JAVA_OPTS -jar app.jar # in a single shell-format CMD
我花了一段时间,但我终于弄清楚/bin/sh -c
在这个用例中的意义是什么。 例如,我们可以使用tini作为入口点
ENTRYPOINT ["tini", "--"]
然后是 CMD 的 shell,但是我们需要使用exec
来替换子 shell,即
CMD exec java $JAVA_OPTS -jar app.jar
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.