Docker容器会在“docker run -d”后自动停止

根据我读过的教程,使用“ docker run -d ”将从图像启动一个容器,容器将在后台运行。 这是它的样子,我们可以看到我们已经有了容器ID。

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

但是如果我运行“ docker ps ”,没有任何返回。

所以我尝试了“ 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 

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

centos dockerfile有一个默认命令bash

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

2017年更新

更新版本的docker授权在分离模式 前台模式下运行容器( -t-i-it

在这种情况下,你不需要任何额外的命令,这就足够了:

 docker run -t -d centos 

bash将在后台等待。
最初在kalyani-chaudhari的回答中有报道,在泽西豆的回答中有详细的说明。

 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 

原文答复(2015)

正如在这篇文章中提到的:

不要用docker run -i -t image your-command ,build议使用-d ,因为你可以用一个命令运行你的容器,而不需要按Ctrl + P + Q来分离容器的terminal。

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

问题是某些应用程序不能在前台运行。 我们如何使它更容易?

在这种情况下,您可以将tail -f /dev/null到您的命令中。
通过这样做,即使您的主命令在后台运行,您的容器也不会停止,因为尾部仍在前台运行。

所以这将工作:

 docker run -d centos tail -f /dev/null 

docker ps会显示仍在运行的centos容器。

从那里,你可以附加到它或从它分离 (或docker exec一些命令)。

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

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

看起来,-t选项没有被很好地logging下来 ,虽然帮助说它“分配一个伪TTY”。

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

 -d 

选项只是在deamon模式下运行一个容器。

所以让你的容器连续运行的技巧是指向Docker中的shell文件,它将保持你的应用程序运行。你可以尝试一个start.sh文件

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

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

如果你不想让任何应用程序运行的话,你可以安装monit来保持docker容器的运行。 请让我们知道,如果这两个案件为你保持你的容器运行。

祝一切顺利

执行命令如下:

 docker run -t -d <image-name> 

如果你想指定端口,那么命令如下:

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

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

 docker ps 

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

所以,如果你的docker入口脚本是一个像下面这样的后台进程:

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

如果稍后没有触发其他前台进程,那么'&'会使容器停止并退出。 所以解决方法就是删除'&'或者在其后面运行另一个前景CMD ,比如

 tail -f server.log 

也许只是我,但在CentOS 7.3.1611和Docker 1.12.6,但我最终不得不使用@VonC&@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 

然后join-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). 

无论出于何种原因,如果tail -f被移除,或者任何-t -d -i选项被省略,上述操作将在执行CMD后退出。

你可以完成你想要的任何一个:

 docker run -t -d <image-name> 

要么

 docker run -i -d <image-name> 

要么

 docker run -it -d <image-name> 

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

另外请注意,Docker文档build议将-i和-t选项组合起来会使其performance得像一个shell。

看到:

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

背景

一个Docker容器运行一个进程(“命令”或“入口点”),保持它的活着。 只要命令继续运行,容器将继续运行。

在你的情况下,命令( /bin/bash ,默认情况下,在centos:latest )会立即退出(因为bash没有连接到terminal并没有任何运行)。

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

你似乎试图做的是保持容器活着,没有守护进程在容器内运行。 这有点奇怪(因为容器在与docker exec进行交互之前没有做任何有用的工作),但是在某些情况下,这样做可能是有意义的。

(你的意思是在容器内进行bash提示吗?这很简单! docker run -it centos:latest

使容器保持在守护进程模式下的一个简单方法是无限地运行sleep infinity作为容器的命令。 这并不依赖于在守护进程模式下保持STDIN打开的奇怪事情。

 $ 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