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

时间:2018-09-24 09:04:15

标签: docker nginx

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

3 个答案:

答案 0 :(得分:1)

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

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

用于这种情况的典型入口点脚本可能看起来像:

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

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

答案 1 :(得分:0)

是的,您要覆盖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;"'

或者,如果您要构建自己的映像,则可以将其作为CMD / Entrypoint放入Dockerfile中。

答案 2 :(得分:0)

我发现,如果我创建自己的容器,则不会执行父容器中的某些命令。尽管事实上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;"