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

Docker container will automatically stop after "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

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

您好,这个问题是因为 docker 如果容器中没有 运行ning 应用程序,容器就会退出。

-d 

选项只是 运行 守护进程模式下的容器。

因此,让您的容器连续 运行ning 的技巧是指向 docker 中的 shell 文件,这将使您的应用程序 running.You 可以尝试使用 start.sh 文件

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

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

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

祝一切顺利

centos dockerfile 有一个默认命令 bash

也就是说,当运行在后台(-d)时,shell立即退出。

2017 年更新

docker 的较新版本授权 运行 一个位于 detached mode and in foreground mode-t-i-it)中的容器

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

docker run -t -d centos

bash 将在后台等待。
这最初是在 kalyani-chaudhari's and detailed in jersey bean's .

中报道的
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 reports :

docker run -t -d alpine/git does not keep the process up.
Had to do: docker run --entrypoint "/bin/sh" -it alpine/git


原始答案 (2015)

this article所述:

Instead of running with docker run -i -t image your-command, using -d is recommended because you can run your container with just one command and you don’t need to detach terminal of container by hitting Ctrl + P + Q.

However, there is a problem with -d option. Your container immediately stops unless the commands keep running in foreground.
Docker requires your command to keep running in the foreground. Otherwise, it thinks that your applications stops and shutdown the container.

The problem is that some application does not run in the foreground. How can we make it easier?

In this situation, you can add tail -f /dev/null to your command.
By doing this, even if your main command runs in the background, your container doesn’t stop because tail is keep running in the foreground.

所以这行得通:

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

或者在 Dockerfile 中:

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

A docker ps 会显示 centos 容器仍在 运行ning.

从那里,您可以 attach to it or detach from it(或 docker exec 一些命令)。

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

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

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

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

tail -f server.log

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

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

似乎是 -t 选项 ,虽然帮助说它 "allocates a pseudo-TTY."

也许只有我一个人,但在 CentOS 7.3.1611 和 Docker 1.12.6 上,但我最终不得不结合使用@VonC 和@Christopher Simon 发布的答案来使它可靠地工作.在此之前我所做的任何事情都不会阻止容器在 运行 CMD 成功后退出。我正在启动 oracle-xe-11Gr2 和 sshd。

Docker文件

...
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).

无论出于何种原因,如果删除了 tail -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 容器 运行 是一个使它保持活动状态的进程("command" 或 "entrypoint")。只要命令继续 运行,容器就会继续 运行。

在你的情况下,命令(/bin/bash,默认情况下,在 centos:latest 上)立即退出(就像 bash 在它没有连接到终端并且没有任何东西时所做的那样) 运行).

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

您似乎想做的是在容器内没有守护进程 运行ning 的情况下使容器保持活动状态。这有点奇怪(因为容器在您与它交互之前不会做任何有用的事情,也许是 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 选项分配了一个 "pseudo-tty"。这会诱使 bash 无限期地继续 运行 因为它认为它连接到交互式 TTY(即使你没有通过 -i 就无法与该特定 TTY 交互).无论如何,这也应该可以解决问题:

$ docker run -t -d centos:latest

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

有同样问题的post下面我已经解释过了

参数顺序很重要

Jersey Beans 的回答(所有 3 个示例)对我有用。经过大量的反复试验后,我意识到参数的顺序很重要。

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

将容器 运行 保持在前台: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>

登录容器shell:

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

我遇到了同样的问题,只需打开另一个带有 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 的 OS 上时,这才有效。

&& /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 运行 -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 运行 -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

我也遇到了同样的问题,只是方式不同。当我创建 docker 容器时。它会自动停止未使用的容器,这些容器只是在后台 运行ning。有时它还会停止正在使用的容器。 在我的情况下,这是因为它之前拥有 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 容器构建。

这 4 个命令都可以让您的 docker 容器 运行:

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

运行 容器处于 foreground/detached 状态有多种选择。但如果您仍然觉得问题没有得到解决,您可以尝试通过查看日志来解决问题。

sudo docker logs -f >> container.log

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

您可以简单地使用:

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