根据我目前阅读的教程,使用"docker run -d"将从image启动一个容器,并且容器将在后台运行。这就是它的样子,我们已经有了container 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

我做错什么了吗?如何解决此问题?


当前回答

背景

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

在您的例子中,命令(默认情况下,centos:latest上的/bin/bash)立即退出(bash在没有连接到终端并且没有什么要运行时也会退出)。

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

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

(您的意思是在容器内获得bash提示符吗?这很简单!Docker运行- centos:最新)

解决方案

让容器无限期地处于守护模式下活动的一个简单方法是运行sleep infinity作为容器的命令。这并不依赖于做一些奇怪的事情,比如在守护进程模式下分配TTY。尽管它确实依赖于一些奇怪的事情,比如把睡眠作为你的主要命令。

$ 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”。这个技巧会继续无限地运行,因为它认为它连接到一个交互式TTY(即使如果不传递-i,您没有办法与那个特定的TTY进行交互)。不管怎样,这个也可以做到:

$ docker run -t -d centos:latest

不能100%确定-t是否会产生其他奇怪的相互作用;如果是的话,请在下方留言。

其他回答

我也遇到了同样的问题,只是打开另一个终端,对我来说很管用:

创建容器:

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

centos dockerfile有一个默认命令bash。

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

更新2017

最新版本的docker授权以分离模式和前台模式运行容器(-t, -i或-it)

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

docker run -t -d centos

bash将在后台等待。 这最初是在kalyani-chaudhari的回答中报道的,并在jersey bean的回答中详细描述。

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

注意,对于alpine, Marinos An在评论中报告:

Docker运行-t -d alpine/git不会保持进程正常运行。 必须这样做:docker run——entrypoint "/bin/sh" - alpine/git


原答案(2015)

如本文所述:

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

但是,-d选项有一个问题。您的容器立即停止,除非命令一直在前台运行。 Docker需要你的命令保持在前台运行。否则,它会认为应用程序停止并关闭容器。

问题是一些应用程序不能在前台运行。我们怎样才能让它变得更简单呢?

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

所以这是可行的:

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

或者在Dockerfile中:

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

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

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

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

-d 

选项是在守护模式下运行容器。

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

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

这个start.sh应该指向一个永不结束的应用程序。

如果你不想让任何应用程序运行,你可以安装monit来保持docker容器运行。 请让我们知道这两个案例是否对你的集装箱运行有效。

愿一切都好!

我已经在下面的帖子中解释了这个问题。

使用“exit”后如何保留docker alpine容器?

我有这段代码片段从我的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