Docker容器将在" docker run -d"之后自动停止。

时间:2015-05-13 08:41:06

标签: docker

根据我到目前为止阅读的教程,使用" docker run -d"将从image启动容器,容器将在后台运行。这就是它的样子,我们可以看到我们已经有了容器ID。

root@docker:/home/root# docker run -d centos
605e3928cdddb844526bab691af51d0c9262e0a1fc3d41de3f59be1a58e1bd1d

但如果我跑了" docker ps "则没有返回任何内容。

所以我尝试了#34; docker ps -a ",我可以看到容器已经退出:

root@docker:/home/root# docker ps -a
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS                         PORTS               NAMES
605e3928cddd        centos:latest         "/bin/bash"         31 minutes ago      Exited (0) 31 minutes ago                          kickass_swartz

我做错了什么?我该如何解决这个问题?

18 个答案:

答案 0 :(得分:374)

centos dockerfile有一个默认命令bash

这意味着,当在后台运行(-d)时,shell会立即退出。

2017年更新

更新版本的docker授权在detached mode foreground mode -t-i或{{1}中的kalyani-chaudhari 中运行容器}})

在这种情况下,您不需要任何其他命令,这就足够了:

-it

bash将在后台等待 这最初是在answerjersey bean中报告的,详细介绍了answeralpine

docker run -t -d centos

请注意,对于 Marinos An in the comments报告this article

  

vonc@voncvb:~$ d ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4a50fd9e9189 centos "/bin/bash" 8 seconds ago Up 2 seconds wonderful_wright 不会保持这个过程   不得不这样做:docker run -t -d alpine/git

原始答案(2015)

attach to it or detach from it中所述:

  

建议使用docker run --entrypoint "/bin/sh" -it alpine/git,而不是使用docker run -i -t image your-command运行,因为您可以只使用一个命令运行容器,而无需通过按 Ctrl + P + Q

     

但是,-d选项存在问题。 除非命令未在前台上运行,否则您的容器会立即停止   Docker要求您的命令继续在前台运行。否则,它认为您的应用程序停止并关闭容器。

     

问题是某些应用程序无法在前台运行。我们怎样才能让它变得更容易?

     

在这种情况下,您可以在命令中添加-d   通过这样做,即使您的主命令在后台运行,您的容器也不会停止,因为尾部在前台继续运行。

所以这会奏效:

tail -f /dev/null

docker run -d centos tail -f /dev/null 会显示centos容器仍在运行。

从那里,你可以https://jsfiddle.net/tusharj/t2gwptys/(或docker ps一些命令。

答案 1 :(得分:47)

根据this answer,添加-t标志将阻止容器在后台运行时退出。然后,您可以使用docker exec -i -t <image> /bin/bash进入shell提示符。

docker run -t -d <image> <command>

似乎-t选项isn't documented very well,虽然帮助说它&#34;分配了一个伪TTY。&#34;

答案 2 :(得分:27)

背景

Docker容器运行一个使其保持活动状态的进程(“命令”或“入口点”)。只要命令继续运行,容器就会继续运行。

在您的情况下,默认情况下,/bin/bash上的命令(centos:latest)立即退出(正如bash没有连接到终端并且没有任何内容可以运行时)。

通常,当您以守护进程模式运行容器(使用-d)时,容器正在运行某种守护进程(如httpd)。在这种情况下,只要httpd守护程序正在运行,容器就会保持活动状态。

您似乎要做的是在容器内运行守护程序进程的情况下保持容器的活动状态。这有点奇怪(因为容器在与它交互之前没有做任何有用的事情,可能是docker exec),但在某些情况下,做这样的事情可能是有意义的。

(你的意思是在容器内找到一个bash提示符吗?这很简单!docker run -it centos:latest

解决方案

在容器模式下无限期地保持容器处于活动状态的一种简单方法是运行sleep infinity作为容器的命令。这并不依赖于在守护进程模式下分配TTY等奇怪的事情。虽然它确实依赖于使用sleep作为主要命令等奇怪的事情。

$ docker run -d centos:latest sleep infinity
$ docker ps
CONTAINER ID  IMAGE         COMMAND          CREATED       STATUS       PORTS NAMES
d651c7a9e0ad  centos:latest "sleep infinity" 2 seconds ago Up 2 seconds       nervous_visvesvaraya

替代解决方案

如cjsimon所示,-t选项分配“伪tty”。这使得bash继续无限期地运行,因为它认为它连接到交互式TTY(即使你没有通过-i也无法与特定的TTY交互)。无论如何,这应该也可以解决问题:

$ docker run -t -d centos:latest

不是100%确定-t是否会产生其他奇怪的互动;如果有,可以在下面发表评论。

答案 3 :(得分:15)

嗨,这个问题是因为如果容器中没有正在运行的应用程序,则docker容器会退出。

-d 

选项只是以deamon模式运行容器。

因此,使容器持续运行的技巧是指向docker中的shell文件,它将使您的应用程序保持运行。您可以尝试使用start.sh文件

Eg: docker run -d centos sh /yourlocation/start.sh

这个start.sh应该指向一个永无止境的应用程序。

如果您不希望任何应用程序运行,您可以安装monit,这将使您的docker容器保持运行。 如果这两个案例对您有效,请告诉我们。

一切顺利

答案 4 :(得分:8)

你可以用以下任何一种方法完成你想要的任务:

docker run -t -d <image-name>

docker run -i -d <image-name>

docker run -it -d <image-name>

其他答案(即tail -f / dev / null)建议的命令参数是完全可选的,并且不需要让容器在后台运行。

另请注意,Docker文档建议组合-i和-t选项会使其表现得像shell。

请参阅:

https://docs.docker.com/engine/reference/run/#foreground

答案 5 :(得分:6)

执行命令如下:

docker run -t -d <image-name>

如果要指定port,则命令如下:

docker run -t -d -p <port-no> <image-name>

使用以下命令验证正在运行的容器:

docker ps

答案 6 :(得分:4)

Docker要求您的命令继续在前台运行。否则,它认为您的应用程序停止并关闭容器。

因此,如果你的docker入口脚本是一个后台进程,如下所示:

/usr/local/bin/confd -interval=30 -backend etcd -node $CONFIG_CENTER &

'&amp;'如果以后没有触发其他前台进程,则使容器停止并退出。 所以解决方案只是删除'&amp;'或者在其后运行另一个前景CMD ,例如

tail -f server.log

答案 7 :(得分:2)

我从docker文件中的ENTRYPOINT运行了以下代码段:

while true
do
    echo "Press [CTRL+C] to stop.."
    sleep 1
done

将构建的docker映像运行为:

docker run -td <image name>

登录到容器外壳:

docker exec -it <container id> /bin/bash

答案 8 :(得分:1)

我也遇到了同样的问题,但方式不同。当我创建 docker 容器时。它会自动停止只是在后台运行的未使用的容器。有时它还会停止正在使用的容器。 在我的情况下,这是因为它之前拥有的 docker.sock 文件的权限。 你需要做的是:-

  1. 再次安装 docker。(当我在 ubuntu 上工作时,我从 here 安装它)

  2. 运行命令更改权限。

    sudo chmod 666 /var/run/docker.sock

  3. 安装 docker-compose(这是可选的,因为我有 compose 文件可以一起创建多个容器)

    sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

    sudo chmod +x /usr/local/bin/docker-compose

  4. 检查版本以确保我拥有最新版本,并且不会因某些降价而出现问题。

  5. 然后我运行 docker 容器构建。

答案 9 :(得分:1)

以交互模式运行docker可能会解决问题。

以下是在有和没有交互模式下运行图像的示例

chaitra @ RSK-IND-BLR-L06:〜/ dockers $ sudo docker run -d -t -i test_again1.0 b6b9a942a79b1243bada59db19c7999cfff52d0a8744542fa843c95354966a18

chaitra @ RSK-IND-BLR-L06:〜/ dockers $ sudo docker ps

容器ID图像命令创建的状态端口名称

chaitra @ RSK-IND-BLR-L06:〜/ dockers $ sudo docker run -d -t -i test_again1.0 bash c3d6a9529fd70c5b2dc2d7e90fe662d19c6dad8549e9c812fb2b7ce2105d7ff5

chaitra @ RSK-IND-BLR-L06:〜/ dockers $ sudo docker ps

容器ID图像命令创建的状态端口名称 c3d6a9529fd7 test_again1.0“ bash” 2秒前最多1秒awesome_haibt

答案 10 :(得分:1)

如果内部任务完成,则Docker容器将退出,因此,即使它没有任何工作或已经完成任务,也要使其保持活动状态,则可以执行docker run -di image。完成docker container ls后,您将看到它正在运行。

答案 11 :(得分:1)

也许只是我,但在CentOS 7.3.1611和Docker 1.12.6上,但我最终不得不使用@VonC&amp; amp; @Christopher Simon让这个工作可靠。在此之前我没有做任何事情会阻止容器在成功运行CMD后退出。我正在启动oracle-xe-11Gr2和sshd。

Dockerfile

...
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' && systemctl enable sshd
...
CMD /etc/init.d/oracle-xe start && /sbin/sshd && tail -f /dev/null

然后添加-d -t和-i以运行

docker run --shm-size=2g --name oracle-db -d -t -i -p 5022:22 -p 5080:8080 -p 1521:1521 centos-oracle:7.3.1611 

最后几个小时后,我的头靠在墙上

ssh -v root@127.0.0.1 -p 5022
...
root@127.0.0.1's password: 
debug1: Authentication succeeded (password).

无论出于何种原因,如果删除尾部-f,或者省略任何-t -d -i选项,则执行CMD后将退出上述内容。

答案 12 :(得分:0)

我遇到了同样的问题,只是打开另一个带有bash的终端对我有用:

创建容器:

docker run -d mcr.microsoft.com/mssql/server:2019-CTP3.0-ubuntu
containerid=52bbc9b30557

启动容器:

docker start 52bbc9b30557

启动bash以保持容器运行:

docker exec -it 52bbc9b30557 bash

您需要的启动过程:

docker exec -it 52bbc9b30557 /path_to_cool_your_app

答案 13 :(得分:0)

如果在Dockerfile的末尾使用CMD,则可以在末尾添加代码。仅当您的Docker构建于ubuntu或任何可以使用bash的操作系统时,这才起作用。

&& /bin/bash

简而言之,Dockerfile的结尾看起来像这样。

...

CMD ls && ... && /bin/bash

因此,如果您在运行docker映像后有任何自动运行,并且任务完成后,bash终端将在docker内部处于活动状态。因此,您可以输入shell命令。

答案 14 :(得分:0)

如果要在容器上进行操作,则需要在前台运行它以使其保持活动状态。

答案 15 :(得分:0)

我在以下具有相同问题的帖子中进行了解释。

How to retain docker alpine container after "exit" is used?

答案 16 :(得分:0)

有同样的问题。分享成功经验

#Run docker image on detached mode with the bash program
$ docker run -it -d test:latest bash
189c9fb6eb61bc8b65983d75be6ce2a543048935c0cb2576358146445c82c381

$ docker ps
CONTAINER ID        IMAGE               COMMAND 
189c9fb6eb61        test:latest         "bash"  

#Get the bash shell on the running container.
$ docker exec -it 189c9fb6eb61 bash
ubuntu@189c9fb6eb61:~$ 

答案 17 :(得分:-2)

参数顺序很重要

Jersey Beans的答案(所有3个示例)都为我工作。经过反复尝试,我意识到参数的顺序很重要。

使容器在后台运行:     docker run -t -d <image-name>

使容器在前台运行:docker run <image-name> -t -d

从Powershell的背景来看,这对我来说并不明显。