如何从 docker shell 脚本(入口点)调用 spring-boot java 应用程序?

How to call a spring-boot java application from docker shell script (entrypoint)?

我有一个 Dockerfile 结尾为:

ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

现在我想 运行 在此之前从 shell 脚本进行一些初始化。所以我必须将其重构为:

ENTRYPOINT[ /entrypoint.sh]

有:

!#/bin/bash
echo "some init"

#TODO
#ENTRYOINT["java", "org.springframework.boot.loader.JarLauncher"]

问题:如何在 shell 脚本中实际模拟 java 入口点?

ShellScript 可以编辑为 运行 普通 Java 文件。

来自 docker 文档:

如果您需要为单个可执行文件编写启动脚本,您可以使用 exec

确保最终可执行文件接收 Unix 信号
!#/bin/bash
echo "some init"

#Execute using linux 'exec' Java launcher
exec java org.springframework.boot.loader.JarLauncher

TL;DR:如果入口点包装器以行 exec "$@" 结尾,那么它将 运行 图像的 CMD。如果您将现在拥有的 ENTRYPOINT 更改为 CMD,那么您将不必在脚本中 hard-code 它。


在您现在拥有的普通 Dockerfile 中,您可以将 ENTRYPOINT 更改为 CMD,而不会影响您使用容器的方式。

FROM openjdk:17
...
# not ENTRYPOINT
CMD ["java", "org.springframework.boot.loader.JarLauncher"]

就其本身而言,这为您提供了一些灵活性;例如,可以直接查看容器内部,或者启动交互式 shell 而不是正常的容器进程。

docker run --rm my-image ls /app
docker run --rm -it my-image sh

现在,如果您有 CMD 这种方式,您可以相当直接地向其添加 ENTRYPOINT 包装器脚本。 The CMD is passed to the ENTRYPOINT as additional arguments 和 shell 调用 exec "$@" 将 运行 作为 CMD.

传递的任何内容
#!/bin/sh
# entrypoint.sh
echo "some init"
touch /init-has-happened
exec "$@"

重要的是,这适用于我上面显示的备用 docker run 命令。备用 docker run 命令替换了 Dockerfile CMD 但保留了 ENTRYPOINT 包装器,因此备用命令在末尾的 exec "$@" 行中得到 运行。

docker run --rm my-image ls -l /init-has-happened
# the file will exist because the entrypoint wrapper creates it