Docker 入口点脚本中的 exec 命令失败

Docker exec command in entrypoint script fails

按照 上的建议(我需要在重新启动容器之前清除临时目录,以修复错误),我使用 CMD 修改了我的 docker 文件, 入口点如下:

ENTRYPOINT ["/app/entrypoint.sh", "/usr/bin/java -Dlog4j.configurationFile=/app/resources/LINUX/${LOG4J_FILE} -Dpa.config=/app/resources/LINUX/${CONFIG_FILE} -jar /app/app.jar"]

并且在 rm -rf 命令之后的入口点文件结束:

exec "$@"

但是docker无法启动容器,它退出了,容器日志显示:

+ exec '/usr/bin/java -Dlog4j.configurationFile=/app/resources/LINUX/${LOG4J_FILE} -Dpa.config=/app/resources/LINUX/${CONFIG_FILE} -jar /app/app.jar' /app/entrypoint.sh: line 7: /usr/bin/java -Dlog4j.configurationFile=/app/resources/LINUX/${LOG4J_FILE} -Dpa.config=/app/resources/LINUX/${CONFIG_FILE} -jar /app/app.jar: No such file or directory - 这是什么意思?怎么了?

您需要将 JSON-array-format 命令行分成单独的单词。因为你已经明确地告诉 Docker 这个的“命令”部分是一个单词,所以它正在 /usr/bin 中寻找一个名为 java -Dlog4j.configurationFile=... 的二进制文件,其中包含空格和选项以及所有作为文件名的一部分,但找不到它。

您通常不希望在 ENTRYPOINT 中嵌入您想要 运行 的命令,尤其是当您使用此包装器布局时。使 ENTRYPOINT 只是以 exec "$@" 结尾的脚本的名称;它必须使用 JSON-array 语法。使 CMD 成为您想要 运行 的实际命令,以更方便的语法为准。 (如果你想扩展环境变量,面向 shell 的语法可能会更好。)

ENTRYPOINT ["/app/entrypoint.sh"]
CMD /usr/bin/java \
  -Dlog4j.configurationFile=/app/resources/LINUX/${LOG4J_FILE} \
  -Dpa.config=/app/resources/LINUX/${CONFIG_FILE} \
  -jar /app/app.jar

我发现这种模式非常普遍和有用,所以我通常建议只对这种包装脚本使用 ENTRYPOINT;更喜欢将启动应用程序的命令作为 CMD,即使您没有入口点包装器。