【问题标题】:Docker exec command in entrypoint script fails入口点脚本中的 Docker exec 命令失败
【发布时间】:2020-04-28 10:46:20
【问题描述】:

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

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 - 这是什么意思?怎么了?

【问题讨论】:

  • 你的图片中是否存在/usr/bin/java
  • 它必须,图像没有改变,我只是更改了代码以通过入口点脚本而不是CMD最后运行该命令,所以我可以在之前运行rm -rf命令......但是无论如何,我刚刚登录到一个覆盖入口点脚本的容器,并手动验证 - 文件在那里:lrwxrwxrwx 1 root root 22 Dec 14 18:14 /usr/bin/java -> /etc/alternatives/java 指向lrwxrwxrwx 1 root root 73 Dec 14 18:14 /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64/jre/bin/java

标签: shell docker environment-variables docker-entrypoint


【解决方案1】:

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

您通常不希望在 ENTRYPOINT 中嵌入要运行的命令,尤其是在您使用此包装器布局时。将ENTRYPOINT 设为以exec "$@" 结尾的脚本名称;它必须使用 JSON 数组语法。使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,即使您没有入口点包装器。

【讨论】:

  • 成功了,谢谢!我仍然不明白这一点.. 它没有明确记录的功能,感觉更像是一个 hack。
猜你喜欢
  • 2019-04-28
  • 2014-12-12
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
  • 2021-08-09
  • 2019-05-28
  • 2015-11-22
  • 2017-09-29
相关资源
最近更新 更多