475

根据我目前阅读的教程,使用“ 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

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

4

20 回答 20

705

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

请注意,对于alpineMarinos An在评论中报告:

docker run -t -d alpine/git不保持进程。
不得不做:docker run --entrypoint "/bin/sh" -it alpine/git


原始答案(2015)

本文所述

建议不要使用 with 运行docker run -i -t image your-command,而是使用 using -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"]

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

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

于 2015-05-13T08:51:05.013 回答
83

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

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

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

于 2016-07-22T10:42:32.823 回答
69

背景

Docker 容器运行一个进程(“命令”或“入口点”)以使其保持活动状态。只要命令继续运行,容器就会继续运行。

在您的情况下,命令(/bin/bash默认情况下为 on 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”。这使 bash 无限期地继续运行,因为它认为它已连接到交互式 TTY(即使如果您不通过,您将无法与该特定 TTY 进行交互-i)。无论如何,这也应该可以解决问题:

$ docker run -t -d centos:latest

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

于 2017-10-23T20:34:13.730 回答
21

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

-d 

选项只是以守护程序模式运行容器。

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

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

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

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

祝一切顺利

于 2015-05-13T08:50:40.927 回答
15

您可以通过以下任一方式完成您想要的:

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

于 2017-09-27T08:16:58.533 回答
13

我从ENTRYPOINT我的 docker 文件中运行了这个代码片段:

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
于 2019-02-04T07:06:30.473 回答
10

执行命令如下:

docker run -t -d <image-name>

如果要指定端口,则命令如下:

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

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

docker ps
于 2017-06-05T13:01:45.707 回答
9

如果里面的任务完成,Docker 容器就会退出,所以如果你想让它保持活动状态,即使它没有任何工作或已经完成它们,你可以做docker run -di image. 完成后,docker container ls您将看到它正在运行。

于 2019-09-02T08:38:38.663 回答
7

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

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

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

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

tail -f server.log
于 2016-06-28T06:44:54.120 回答
5

也许只有我一个人,但在 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 后上述内容将退出。

于 2017-05-01T15:40:52.997 回答
5

如果您在 Dockerfile 末尾使用 CMD,您可以在末尾添加代码。这仅在您的 docker 构建在 ubuntu 或任何可以使用 bash 的操作系统上时才有效。

&& /bin/bash

简而言之,你的 Dockerfile 的结尾看起来像这样。

...

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

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

于 2019-07-25T19:50:51.037 回答
2

我在下面有同样问题的帖子中解释了它。

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

于 2018-07-02T09:40:24.980 回答
2

以交互模式运行 docker 可能会解决此问题。

这是使用和不使用交互模式运行图像的示例

chaitra@RSK-IND-BLR-L06:~/dockers$ sudo docker run -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 run -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

于 2020-04-09T06:03:03.037 回答
1

我遇到了同样的问题,只是打开另一个带有 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
于 2019-06-22T21:36:32.050 回答
1

我也面临同样的问题,但方式不同。当我创建 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 容器构建。

于 2021-06-20T08:33:54.643 回答
1

您可以简单地使用:

docker container run -d -it <container name or id> /bin/bash
于 2022-02-18T05:28:24.420 回答
0

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

docker run -td centos
docker run -dt centos
docker run -t -d centos
docker run -d -t centos
于 2022-01-17T12:51:35.360 回答
0

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

sudo docker logs -f >> container.log

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

于 2022-01-21T06:25:59.433 回答
-1

论证顺序很重要

Jersey Beans 答案(所有 3 个示例)对我有用。经过相当多的反复试验,我意识到论点的顺序很重要。

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

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

对我来说,来自 Powershell 背景并不明显。

于 2018-12-28T09:06:57.493 回答
-1

如果要对容器进行操作,则需要在前台运行它以使其保持活力。

于 2020-02-18T03:09:42.073 回答