我已经看到了一堆教程,似乎做同样的事情,我试图做,但出于某种原因,我的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循环来保持它,但是怎样才能使它不退出呢?


当前回答

动机:

在docker容器中运行多个进程并没有什么错。如果你喜欢使用docker作为一个轻量级的VM,那就这样吧。其他人则喜欢将他们的应用程序拆分为微服务。我想:一个容器里的LAMP堆栈?就好了。

答案是:

坚持使用一个好的基础图像,如phusion基础图像。可能还有其他的。请发表评论。

这只是另一个请求监督的请求。因为phusion base image除了提供cron和locale setup之类的东西外,还提供了监督器。当运行这样一个轻量级VM时,你想要设置的东西。它还提供了到容器的ssh连接。

phusion镜像本身将启动并继续运行,如果你发出以下基本的docker运行语句:

moin@stretchDEV:~$ docker run -d phusion/baseimage
521e8a12f6ff844fb142d0e2587ed33cdc82b70aa64cce07ed6c0226d857b367
moin@stretchDEV:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS
521e8a12f6ff        phusion/baseimage   "/sbin/my_init"     12 seconds ago      Up 11 seconds

或者非常简单:

如果基本图像不适合你……对于快速CMD,让它保持运行,我认为bash是这样的:

CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"

或者busybox是这样的:

CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"

这很好,因为它将在docker停止时立即退出。

在集装箱被码头工人强行杀死之前,只是单纯的睡眠或猫将需要几秒钟。

更新

作为对Charles Desbiens关于在一个容器中运行多个进程的回应:

This is an opinion. And the docs are pointing in this direction. A quote: "It’s ok to have multiple processes, but to get the most benefit out of Docker, avoid one container being responsible for multiple aspects of your overall application." For sure it obviously much more powerful to devide your complex service into multiple containers. But there are situations where it can be beneficial to go the one container route. Especially for appliances. The GitLab Docker image is my favourite example of a multi process container. It makes deployment of this complex system easy. There is no way for mis-configuration. GitLab retains all control over their appliance. Win-Win.

其他回答

我刚刚遇到了同样的问题,我发现如果你运行带有-t和-d标志的容器,它会继续运行。

docker run -td <image>

下面是标志的作用(根据docker run——help):

-d, --detach=false         Run container in background and print container ID
-t, --tty=false            Allocate a pseudo-TTY

最重要的是-t标志。-d只是让你在后台运行容器。

从docker引擎v1.25开始,就有一个名为init的选项。 Docker-compose从3.7版开始包含此命令。

所以当我运行一个容器时,我当前的CMD应该运行到无穷大:

CMD ["sleep", "infinity"]

然后运行它,使用:

docker build
docker run --rm --init app

crf。 Rm文档和init文档

动机:

在docker容器中运行多个进程并没有什么错。如果你喜欢使用docker作为一个轻量级的VM,那就这样吧。其他人则喜欢将他们的应用程序拆分为微服务。我想:一个容器里的LAMP堆栈?就好了。

答案是:

坚持使用一个好的基础图像,如phusion基础图像。可能还有其他的。请发表评论。

这只是另一个请求监督的请求。因为phusion base image除了提供cron和locale setup之类的东西外,还提供了监督器。当运行这样一个轻量级VM时,你想要设置的东西。它还提供了到容器的ssh连接。

phusion镜像本身将启动并继续运行,如果你发出以下基本的docker运行语句:

moin@stretchDEV:~$ docker run -d phusion/baseimage
521e8a12f6ff844fb142d0e2587ed33cdc82b70aa64cce07ed6c0226d857b367
moin@stretchDEV:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS
521e8a12f6ff        phusion/baseimage   "/sbin/my_init"     12 seconds ago      Up 11 seconds

或者非常简单:

如果基本图像不适合你……对于快速CMD,让它保持运行,我认为bash是这样的:

CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"

或者busybox是这样的:

CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"

这很好,因为它将在docker停止时立即退出。

在集装箱被码头工人强行杀死之前,只是单纯的睡眠或猫将需要几秒钟。

更新

作为对Charles Desbiens关于在一个容器中运行多个进程的回应:

This is an opinion. And the docs are pointing in this direction. A quote: "It’s ok to have multiple processes, but to get the most benefit out of Docker, avoid one container being responsible for multiple aspects of your overall application." For sure it obviously much more powerful to devide your complex service into multiple containers. But there are situations where it can be beneficial to go the one container route. Especially for appliances. The GitLab Docker image is my favourite example of a multi process container. It makes deployment of this complex system easy. There is no way for mis-configuration. GitLab retains all control over their appliance. Win-Win.

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

Along with having something along the lines of : ENTRYPOINT ["tail", "-f", "/dev/null"] in your docker file, you should also run the docker container with -td option. This is particularly useful when the container runs on a remote m/c. Think of it more like you have ssh'ed into a remote m/c having the image and started the container. In this case, when you exit the ssh session, the container will get killed unless it's started with -td option. Sample command for running your image would be: docker run -td <any other additional options> <image name>

这适用于docker 20.10.2版本