Supervisor 作为我的容器 运行 多个入口点的一种方式

Supervisor as a way to run multiple entrypoints for my container

我需要在我的容器启动时 运行 一个脚本。 (我的脚本根据传入的部署环境变量创建一个 json 文件,供我的 SPA 应用用作配置。)我的容器基于 Nginx container.

但是 Dockerfile 不允许超过一个 ENTRYPOINT,而 Nginx 容器已经有一个(我想我需要保留在那里,这样它才能正常工作。)

我发现了这个问题:Docker multiple entrypoints. It's accepted answer suggests that I use Supervisor to accomplish what I need. I was ready to try that out, but one of the alternate answers 只是使用了一个脚本(这是我看到这个答案之前的计划)。在评论中,这个解决方案(使用脚本)引起了关注。它说:

Supervisor is arguably better, since it can restart your processes if they die, has configurable logging options, can receive commands remotely over RPC, etc.

这里提到的“如果它们死了它可以重新启动你的进程”让我有点担心。我不确定那是什么意思。我不希望我的脚本在完成后重新 运行。 (它在容器启动时创建 json 文件,之后就不需要了。)

主管会让我的脚本一遍又一遍地重新运行吗?

或者我可以使用 supervisor 来 运行 Nginx 的 /docker-entrypoint.sh 脚本和我的脚本吗?还是我应该把它们连在一起,让 supervisor 不参与?

My script creates a json file from the passed in deployment environment variables for my SPA app to use as configuration.

这在入口点脚本中很简单。您可以编写一个脚本来执行初始设置,然后启动主进程(对于您的特定情况有一个“但是”):

#!/bin/sh
/app/build-config-json -o /etc/nginx/config.json # or whatever
# --more--

My container is based on the Nginx container ... and the Nginx container already has [an ENTRYPOINT]

通常您会以 exec "$@" 结束入口点脚本以启动主容器进程。在这种情况下,您可以改为启动原始入口点脚本

# ... the rest of the first-time setup ...
exec /docker-entrypoint.sh "$@"

在您的 Docker 文件中,您可以指定新的 ENTRYPOINT,但是当您这样做时,您还需要重复原来的 CMD。这意味着这种方法通常需要对底层图像有一些了解;它的 Docker 文件是理想的,但您可以从 docker historydocker inspect.

中找到 ENTRYPOINTCMD
ENTRYPOINT ["/wrapped-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

如果可能的话,我会避免supervisord。它围绕重新启动进程和管理日志记录的选项是 Docker 已经为您完成的事情。启动时容器初始化不是必需的。

My script creates a json file from the passed in deployment environment variables for my SPA app to use as configuration. My container is based on the Nginx container.

如果您查看 link 的 Dockerfile,它会启动一个 docker-entrypoint.sh 脚本作为 ENTRYPOINTThat script 在同一 GitHub 存储库的同一目录中,并且 运行s

find "/docker-entrypoint.d/" -follow -type f -print | sort -n | while read -r f; do
    case "$f" in
        *.sh)
            if [ -x "$f" ]; then
                echo >&3 "[=10=]: Launching $f";
                "$f"
            ...
            fi
            ;;
    esac
done

因此,对于这个特定的基础映像,如果您将初始化脚本放在 /docker-entrypoint.d 中,它被命名为 *.sh,并且它是可执行的,那么现有的 ENTRYPOINT 将 运行 在容器启动时为您提供;你不必覆盖任何东西。

FROM nginx:1.19
COPY build-config-json /docker-entrypoint.d/30-build-config-json.sh
RUN chmod +x /docker-entrypoint.d/30-build-config-json.sh
# End of file

默认打包还包括 a script,它将 运行 envsubst/etc/nginx/templates 中的任何 *.template 文件上生成相应的配置文件 /etc/nginx/conf.d,如果这正是您的启动顺序所需要的。