【问题标题】:How to run Nginx within a Docker container without halting?如何在不停止的情况下在 Docker 容器中运行 Nginx?
【发布时间】:2013-09-22 13:37:18
【问题描述】:

我在 Docker 容器上安装了 Nginx,并尝试像这样运行它:

docker run -i -t -p 80:80 mydockerimage /usr/sbin/nginx

问题在于 Nginx 的工作方式是初始进程立即生成一个主 Nginx 进程和一些工作人员,然后退出。由于 Docker 只监视原始命令的 PID,因此容器会停止。

如何防止容器停止?我需要能够告诉它绑定到第一个子进程,或者阻止 Nginx 的初始进程退出。

【问题讨论】:

    标签: linux nginx docker


    【解决方案1】:

    为了扩展 Charles Duffy 的回答,Nginx 使用 daemon off 指令在前台运行。如果不方便放在配置文件中,我们可以直接在命令行中指定。这样可以很容易地在调试模式(前台)下运行,并通过更改命令行参数直接切换到在生产模式下(后台)运行。

    在前台运行:

    nginx -g 'daemon off;'
    

    在后台运行:

    nginx
    

    【讨论】:

    • 有人能解释一下“-g”到底是什么吗?我在文档中找不到这个开关,只有一个使用 nginx 的例子。
    • @red888,设置全局配置选项。
    • CMD 将是 CMD ["nginx", "-g", "daemon off;"] for docker
    • 最后没有分号就死了
    • 奇怪的是-g 'daemon off;' 似乎对我不起作用。只将该行放在配置文件中似乎有效。
    【解决方案2】:

    nginx,像所有表现良好的程序一样,可以配置为不进行自我守护。

    使用http://wiki.nginx.org/CoreModule 中描述的daemon off 配置指令。

    【讨论】:

    • 谢谢!澄清一下,这意味着编辑 /etc/nginx/nginx.conf 并添加“daemon off;”在顶部(即不在服务器或其他指令内)
    • @LeonidShevtsov ...您的意思是没有在 1.0.9 之前被认可用于生产用途。关于就地升级的长期警告,对于以 Docker 方式做事的人来说并不重要。
    • 他们现在似乎在服务器端进行了重定向(到nginx.org/en/docs/ngx_core_module.html)。
    【解决方案3】:

    要扩展 John 的答案,您还可以使用以下 Dockerfile CMD 命令(如果您希望它在没有其他参数的情况下自行启动)

    CMD ["nginx", "-g", "daemon off;"]
    

    【讨论】:

      【解决方案4】:

      仅供参考,截至今天(2019 年 10 月 22 日)official Nginx docker images 都有线路:

      CMD ["nginx", "-g", "daemon off;"]
      

      例如https://github.com/nginxinc/docker-nginx/blob/23a990403d6dbe102bf2c72ab2f6a239e940e3c3/mainline/alpine/Dockerfile#L117

      【讨论】:

        【解决方案5】:

        将此命令添加到 Dockerfile 可以禁用它:

        RUN echo "daemon off;" >> /etc/nginx/nginx.conf
        

        【讨论】:

          【解决方案6】:

          这里有一个运行 nginx 的 Dockerfile 示例。正如查尔斯所提到的,它使用daemon off 配置:

          https://github.com/darron/docker-nginx-php5/blob/master/Dockerfile#L17

          【讨论】:

          【解决方案7】:

          要添加 Tomer 和 Charles 的答案,

          在 Docker 容器中使用入口点在前台运行 nginx 的语法:

          ENTRYPOINT nginx -g 'daemon off;' 
          

          不直接相关,但要使用 Entrypoint 运行多个命令:

          ENTRYPOINT /bin/bash -x /myscripts/myscript.sh && nginx -g 'daemon off;' 
          

          【讨论】:

          • Nitb 正在添加到 Tomer,Tomer 正在添加到 John,而 John 正在添加到 Charles。如果这个网站有公共编辑功能就好了。
          【解决方案8】:

          使用 supervisord 或 runit[1] 进行服务管理也是个好主意。

          [1]https://github.com/phusion/baseimage-docker

          【讨论】:

            【解决方案9】:

            对于所有来这里尝试在 docker 中运行 nginx 映像的人 容器,它将作为服务运行

            由于没有完整的 Dockerfile,这是我的整个 Dockerfile 解决问题。

            很好,工作正常。感谢这里的所有答案,以解决最终的 nginx 问题。

            FROM ubuntu:18.04
            MAINTAINER stackoverfloguy "stackoverfloguy@foo.com"
            RUN apt-get update -y
            RUN apt-get install net-tools nginx ufw sudo -y
            RUN adduser --disabled-password --gecos '' docker
            RUN adduser docker sudo
            RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
            USER docker
            RUN sudo ufw default allow incoming
            RUN sudo rm /etc/nginx/nginx.conf
            RUN sudo rm /etc/nginx/sites-available/default
            RUN sudo rm /var/www/html/index.nginx-debian.html
            VOLUME /var/log
            VOLUME /usr/share/nginx/html
            VOLUME /etc/nginx
            VOLUME /var/run
            COPY conf/nginx.conf /etc/nginx/nginx.conf
            COPY content/* /var/www/html/
            COPY Dockerfile /var/www/html
            COPY start.sh /etc/nginx/start.sh
            RUN sudo chmod +x /etc/nginx/start.sh
            RUN sudo chmod -R 777 /var/www/html
            EXPOSE 80
            EXPOSE 443
            ENTRYPOINT sudo nginx -c /etc/nginx/nginx.conf -g 'daemon off;'
            

            然后运行它:

            docker run -p 80:80 -p 443:443 -dit
            

            【讨论】:

            • 没有你的“start.sh”脚本不是很有用。如果你对你的 HTML 内容有 777 权限,如果你的容器被入侵,攻击者就可以更改内容。为什么任何用户都需要写入容器中的任何内容?还有为什么要添加 docker 用户,然后使用 sudo 来做所有事情呢?同样,如果您受到损害:拥有 sudo 可能是一个问题,您不需要它。保持容器纤薄。或者使用懂安全的人写的 docker hub 的 nginx 镜像。
            【解决方案10】:

            在 DockerHub 上官方 NGINX 镜像的官方注释中指出:

            如果您在 Dockerfile 中添加自定义 CMD,请务必在 CMD 中包含-g daemon off;,以便 nginx 留在前台, 以便 Docker 可以正确跟踪该过程(否则您的 容器将在启动后立即停止)!

            这让我觉得删除 CMD [] 可能会首先防止此问题发生?

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-08-17
              • 2017-04-25
              • 2019-07-27
              • 1970-01-01
              • 2018-01-10
              相关资源
              最近更新 更多