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 run -t -d alpine/git
无法保持进程运行。
必须执行:docker run --entrypoint "/bin/sh" -it alpine/git
原始答案(2015年)
如this article所述:
不要使用 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 exec
执行一些命令)。
然而,正如bviktor在评论中所指出的:
覆盖入口点(entrypoint)将破坏您的Dockerfile,如果它有任何指定的内容。
systemd
尤其值得关注。
跟踪/dev/null
听起来也不是很令人信服:实质上,您会用完全不必要的系统调用轰击您的系统。
使用另一种解决方案看起来要好得多。
这依赖于sleep infinity
,这是GNU coreutils扩展,在POSIX中没有考虑到。
docker run -it -d <image> /bin/bash
解决了它。这个命令会启动一个交互式的bash shell,并且不会关闭容器,因为bash shell进程在活动状态。 - Rtsne42