在 nginx 之上的容器中运行自己的逻辑



我正在构建我想在Docker容器中托管的SPA应用程序。应用程序需要一些配置(例如后端的 URL)。我决定创建读取环境变量并组装配置文件的简短 bash 脚本,但如果我尝试通过 CMD 或 ENTRYPOINT 运行它,它会立即死亡。我想我覆盖了原始 docker 文件中的入口点?当我完成准备这个文件时,我真的需要手动启动nginx吗?

在这种情况下,您很容易:官方 nginx 映像不会声明 ENTRYPOINT,因此您可以添加自己的映像,而不会与基本映像中的任何内容冲突。 这里的重要细节:

  • 当入口点退出时,容器完成
  • 入口点将 CMD 或docker run命令作为参数传递
  • 如果入口点是 shell 脚本,则通常希望以exec "$@"结尾

此类操作的典型入口点脚本可能如下所示:

#!/bin/sh
sed -i.bak -e "s/EXTERNAL_URL/$EXTERNAL_URL/g" /etc/nginx/nginx.conf
exec "$@"

(对于这个特定的任务,我发现 envsubst 非常有用,但我不认为它存在于基于 Alpine 的映像中;它不是一个"标准"工具,但它将存在于一个完整的基于 GNU 的运行时环境中,就像基于 Debian 的映像一样。 它遍历文件并将$VARIABLE引用替换为匹配环境变量的内容。

是的,您正在覆盖 CMD。

推荐方式:

尽可能尝试在您的应用程序中使用环境变量,这样您就不需要更改官方 nginx 容器的入口点/cmd。

如果不可能:

Nginx Dockerfile 使用"nginx", "-g", "daemon off;"作为 cmd,您可以通过以下方式覆盖它:

docker run -d --name yourapp-nginx <put other required docker switches here> <your image name:tag> /bin/sh -c '/path/to/yourscript.sh && /usr/sbin/nginx -g "daemon off;"'

或者,如果您正在构建自己的映像,则可以将其作为 Dockerfile 中的 CMD/入口点。

我发现如果我创建自己的容器,则不会执行父容器中的某些命令。尽管 nginx 图像公开了端口 80,但我不得不添加 EXPOSE 命令来挖掘一个

FROM nginx
ADD dist/* /usr/share/nginx/html/
EXPOSE 80/tcp
COPY docker-entrypoint.sh /usr/local/bin/ 
ENTRYPOINT ["docker-entrypoint.sh"]

此外,我必须在 docker-entrypoint.sh 中手动启动nginx:

#!/bin/bash
echo "{ backendUrl: '$BACKEND_URL'}" >> /usr/share/nginx/html/config
exec "$@"
nginx -g "daemon off;"

最新更新