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。
看到:
背景
一个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