我已经看到了一堆教程,似乎做同样的事情,我试图做,但出于某种原因,我的Docker容器退出。基本上,我在Docker容器中设置了一个web服务器和几个守护进程。我通过一个名为run-all.sh的bash脚本来完成最后的部分,我在Dockerfile中通过CMD运行该脚本。Run-all.sh看起来像这样:

service supervisor start
service nginx start

我在Dockerfile中启动它,如下所示:

CMD ["sh", "/root/credentialize_and_run.sh"]

我可以看到,当我手动运行(即使用-t /bin/bash进入映像)时,所有服务都正确启动,并且当我运行映像时,一切看起来都正确运行,但一旦它完成启动我的进程,它就退出了。我希望进程无限期地运行,据我所知,容器必须一直运行才能实现这一点。然而,当我运行docker ps -a时,我看到:

➜  docker_test  docker ps -a
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS                      PORTS               NAMES
c7706edc4189        some_name/some_repo:blah   "sh /root/run-all.sh   8 minutes ago       Exited (0) 8 minutes ago                        grave_jones

到底发生了什么事?为什么它令人兴奋?我知道我可以在bash脚本的末尾放一个while循环来保持它,但是怎样才能使它不退出呢?


当前回答

在一个变量(例如$NGNIX_PID)中捕获ngnix进程的PID,并在入口点文件do的末尾

wait $NGNIX_PID 

通过这种方式,容器应该一直运行到ngnix激活,当ngnix停止时,容器也会停止

其他回答

如果您正在使用Dockerfile,请尝试:

ENTRYPOINT ["tail", "-f", "/dev/null"]

(显然这只是为了开发目的,你不需要让容器保持活动状态,除非它正在运行一个进程。nginx…)

你可以像兄弟@Sa'ad提到的那样,不带任何参数地运行plain cat,简单地让容器工作(实际上什么都不做,只是等待用户输入)(Jenkins的Docker插件也做同样的事情)

这并不是你真正应该如何设计Docker容器。

在设计Docker容器时,你应该让它只有一个进程在运行(也就是说,你应该为Nginx准备一个容器,为它正在运行的应用程序准备一个容器);此外,该进程应该在前台运行。

当进程本身退出时,容器将“退出”(在您的示例中,该进程就是您的bash脚本)。


然而,如果你真的需要(或想要)在Docker容器中运行多个服务,可以考虑从“Docker Base Image”开始,它使用runit作为伪init进程(当Nginx和Supervisor运行时,runit将保持在线),当其他进程运行时,runit将保持在前台。

他们有大量的文档,所以你应该能够很容易地实现你想要做的事情。

在一个变量(例如$NGNIX_PID)中捕获ngnix进程的PID,并在入口点文件do的末尾

wait $NGNIX_PID 

通过这种方式,容器应该一直运行到ngnix激活,当ngnix停止时,容器也会停止

确保你添加了daemon;或者使用CMD ["nginx", "-g", "daemon off;"根据nginx的官方图片

然后使用以下命令运行监控器作为服务,nginx作为前台进程,以防止容器退出

服务管理启动&& nginx

在某些情况下,容器中需要有多个进程,因此强制容器只有一个进程是行不通的,而且会在部署中产生更多问题。

所以你需要了解其中的利弊,并做出相应的决定。