Docker容器将在“Docker run -d"

根据我读到目前为止的教程,使用"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

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

741898 次浏览

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

-d

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

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

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

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

如果你不想让任何应用程序运行,你可以安装monit,它将保持docker容器运行。 请让我们知道这两种情况是否对您的容器运行有效

愿一切都好!

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

注意,对于alpine马里诺一个报告在评论中:

docker run -t -d alpine/git不保持进程正常运行。
docker run --entrypoint "/bin/sh" -it alpine/git


原答案(2015)

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

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

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

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

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

所以这是可行的:

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

或者在Dockerfile中:

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

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

从那里,你可以依附于它或脱离它(或docker exec某些命令)。

Docker需要你的命令保持在前台运行。否则,它会认为应用程序停止并关闭容器。

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

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

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

tail -f server.log

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

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

似乎-t选项没有很好的记录,尽管帮助说它“分配一个伪tty”。

也许只有我,但在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

然后添加-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后退出。

执行命令如下:

docker run -t -d <image-name>

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

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

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

docker ps

你可以通过以下任何一种方式实现你想要的:

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

背景

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

$ docker run -t -d centos:latest

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

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

“exit”后如何保留docker alpine container;使用?< / >

论证顺序很重要

Jersey Beans的答案(所有3个例子)对我很有用。经过相当多的尝试和错误之后,我意识到论点的顺序很重要。

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

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

对于我这种拥有Powershell背景的人来说,这一点并不明显。

我在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

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

创建容器:

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

如果你在Dockerfile的末尾使用CMD,你所能做的就是在末尾添加代码。只有当你的docker构建在ubuntu上,或者任何可以使用bash的操作系统上时,这才会起作用。

&& /bin/bash

简单地说,Dockerfile的结尾看起来像这样。

...


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

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

如果Docker容器内的任务完成,容器就退出,所以如果你想让它存活,即使它没有任何任务或已经完成任务,你可以执行docker run -di image。在你执行docker container ls之后,你会看到它正在运行。

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

在交互模式下运行docker可能会解决这个问题。

下面是使用和不使用交互模式运行映像的示例

chaitra@RSK-IND-BLR-L06:~/dockers$ sudo docker run -d -t -i test_again1.0 . exe b6b9a942a79b1243bada59db19c7999cfff52d0a8744542fa843c95354966a18 < / p >

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 . sh c3d6a9529fd70c5b2dc2d7e90fe662d19c6dad8549e9c812fb2b7ce2105d7ff5 < / p >

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

容器ID IMAGE命令CREATED STATUS端口名称 c3d6a9529fd7 test_again1.0 "bash" 2 seconds ago Up 1秒awesome_haibt

. bb0
我也面临着同样的问题,但方式不同。当我创建docker容器时。它会自动停止正在后台运行的未使用的容器。有时它还会停止正在使用的容器。 在我的情况下,这是因为docker的许可。Sock文件,它早先有。 你需要做的是:-

  1. 重新安装docker。(因为我在ubuntu上工作,我从在这里安装它)

  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容器构建。

这4个命令都可以保持docker容器的运行:

docker run -td centos
docker run -dt centos
docker run -t -d centos
docker run -d -t centos

在前台/分离状态下运行容器有多个选项。但是,如果您仍然觉得问题没有解决,您可以尝试通过查看日志来解决问题。

Sudo docker logs -f >>container.log

此外,您还可以使用——details来显示提供给日志的额外详细信息。

你可以简单地使用:

docker container run -d -it <container name or id> /bin/bash

Dockerfile中应用程序的错误路径:

我正在使用Alpine Linux将应用程序从RHEL服务器迁移到Docker容器。

在构建过程中没有错误,所以我很惊讶地看到容器立即退出!

第一停靠港:

docker logs <containerID>

这揭示了我在Dockerfile中提供给CMD的二进制文件的路径是伪造的:

line 0: /sbin/postfix: not found

好吧,这告诉我<强> < /如何强大的>的东西坏了,但不是特别<强>,< / >强:我仍然需要在Alpine Linux中的二进制文件的正确路径……

故障排除:

谷歌没有显示它的正确路径,所以我添加了以下一行到我的Dockerfile:

RUN which postfix

然后我检查了我的构建日志- 由附加到我的构建命令的下面命令提供-以检索RUN which postfix的值

 --progress=plain > /path/to/build.log 2>&1

解决办法:

我删除了这个测试构建,在Dockerfile中提供了正确的路径- /usr/sbin/postfix -到CMD,删除RUN which postfix并运行另一个构建。

瞧;这个过程现在还没有结束。

所以duff路径导致容器立即退出…

  • 首先,你需要检查是否有容器正在运行 输入命令,李< / >

Docker ps -all

  • 如果有容器正在运行,那么停止它们 输入命令,李< / >

docker stop容器Id

  • 现在,最后使用以下命令..........运行docker

  • docker运行-t -p 2020:3000 dockerImageName

因此,打开你的谷歌chrome浏览器并访问localhost: 2020

恭喜:)