例如,如果我尝试以下操作: - docker run -i -t foo /bin/bash 或 - docker attach foo (对于已运行的容器)
这两种方法都可以让我进入容器的终端环境,那么如何退出容器的终端环境而不停止它?
使用 exit 和 CTR+C 都会停止容器。
按下 Ctrl+p ,然后按下 Ctrl+q。这将帮助您将交互模式转换为守护进程模式。
一旦连接到一个容器,用户使用
CTRL-p CTRL-q
键序列分离并使其保持运行状态。这个分离键序列可以使用detachKeys
属性进行自定义设置。[...]
更新: 如下面回答中提到的,Ctrl+p,Ctrl+q现已将交互模式转换为守护进程模式。
好的,Ctrl+C(或 Ctrl+\)应该会使您从容器中分离出来,但是由于您的主进程是bash,它会杀死容器。
Docker的一个小课程。 容器不是真正的全功能操作系统。当您运行容器时,启动的进程将获取PID 1并假定init权限。因此,当该进程终止时,守护程序会停止容器,直到启动新进程(通过docker start)。(有关此问题的更多解释,请参见http://phusion.github.io/baseimage-docker/#intro)
如果您想要一直在分离模式下运行的容器,我建议您使用
docker run -d foo
在容器中运行ssh服务器(最简单的方法是按照dockerizing openssh教程进行操作https://docs.docker.com/engine/examples/running_ssh_service/)。
或者您可以通过重新启动容器来实现
docker start foo
(默认情况下它将被分离)
docker container attach --sig-proxy=false mycontainer
附加到一个已经运行的容器,CTRL-C将会分离而不停止该容器。为了一次性启动并分离,我使用docker container start mycontainer;docker container attach --sig-proxy=false mycontainer
。 - Ashley我深入研究了这个问题,以上所有答案都有一定的道理。这完全取决于容器的启动方式。以下是容器启动时需要考虑的几点:
-t
)-i
)^P^Q
确实有效,但是只有在使用-t
和-i
启动容器时才有效:[berto@g6]$ docker run -ti -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
b26e39632351192a9a1a00ea0c2f3e10729b6d3e22f8e0676d6519e15c08b518
[berto@g6]$ docker attach test
# here I typed ^P^Q
read escape sequence
# i'm back to my prompt
[berto@g6]$ docker kill test; docker rm -v test
test
test
ctrl+c
确实可以工作,但是只有在使用-t
(不带-i
)启动容器时才能工作:[berto@g6]$ docker run -t -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
018a228c96d6bf2e73cccaefcf656b02753905b9a859f32e60bdf343bcbe834d
[berto@g6]$ docker attach test
^C
[berto@g6]$
有一种方法可以在不杀死容器的情况下进行分离; 您需要另一个 shell。简而言之,在另一个 shell 中运行以下命令即可分离并保持容器运行:pkill -9 -f 'docker.*attach'
(注意!使用 sigkill 的 -9 对于防止“attach”进程将信号传播到正在运行的容器非常重要。)
[berto@g6]$ docker run -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
b26e39632351192a9a1a00ea0c2f3e10729b6d3e22f8e0676d6519e15c08b518
[berto@g6]$ docker attach test
# here I typed ^P^Q and doesn't work
^P
# ctrl+c doesn't work either
^C
# can't background either
^Z
# go to another shell and run the `pkill` command above
# i'm back to my prompt
[berto@g6]$
为什么?因为你杀死的是连接你到容器的进程,而不是容器本身。
kill -9
信号不这样做。进程被终止了,没有任何补救措施。我的猜测是,其他信号让容器有机会关闭,而-9
则不允许。 - bertowhile true
替换 while [ 1 ]
。[
命令,也就是 test
命令在这里并不起作用。无论是 [ 0 ]
还是 [ 1 ]
都会返回零,所以循环会一直执行。true
和 false
是命令,分别成功和失败地什么都不做。 - SenhorLucas如果你执行 "docker attach "容器id"" 命令,你会进入到这个容器中。
如果你想退出容器但又不想停止它,那么你需要按下Ctrl+P+Q。
我认为Ashwin的答案是最正确的,我的旧答案如下。
docker run -dti foo bash
然后您可以进入容器并使用以下命令运行bash:
docker exec -ti ID_of_foo bash
不需要安装sshd :)
docker attach
更标准,通过重新附加到第一个bash运行。 docker exec
在这里也可以工作,但是它会创建一个新的bash进程,除了第一个进程之外。当然,该进程是在第一个进程的相同上下文/环境/容器中创建的,但它是不同的(类比于在您喜欢的终端仿真器中打开一个新的终端选项卡)。 - thiagowfxdocker-compose run -d --name app_tests app spring server
,然后我可以通过将vscode测试命令设置为docker exec -ti app_tests spring rspec
来运行测试。 - wiggles尝试使用CTRL+P, CTRL+Q将交互模式转换为守护进程。
如果这不能生效并且您是通过docker attach
连接的,您可以通过终止docker attach
进程来分离连接。
更好的方法是使用sig-proxy参数以避免将CTRL+C传递到容器中:
docker attach --sig-proxy=false [container-name]
docker run
命令也有相同的选项可用。
php:7.3-apache
不起作用。 - MKaama这些a
、ctrl-a
、X
或ctrl-\\
值都是有效的键序列示例。要为所有容器配置不同的默认配置键序列,请参见Configuration文件部分。
注意:此功能适用于docker版本1.10+(在回答时,当前版本为18.03)
如果您只想在容器内查看进程的输出,可以使用简单的docker container logs -f <container id>
。
-f
标志使得容器的输出会被实时跟随
和更新。非常有用于调试或监控。
ctrl+p+ctrl+q
对我来说不起作用,原因不明。 - lasec0203docker run -d -i -t f63181f19b2f /bin/bash
它将为这个镜像(Ubuntu)ID f63181f19b2f
创建一个新的容器。容器将在分离模式下运行(在后台运行),此时一个小进程 tty
bash shell 将在后台运行。因此,只要 bash shell 进程没有被杀死,容器就会继续运行。
要连接到正在运行的后台容器,请使用
docker attach b1a0873a8647
如果您想在不退出容器的情况下分离(而不杀死bash shell),则默认情况下,您可以使用ctrl-p,q
。这将使容器退出而不退出容器(在后台运行,也就是说,不杀死bash shell)。
您可以在附加容器时传递自定义命令。
docker attach --detach-keys="ctrl-s" b1a0873a8647
这次ctrl-p,q
的转义序列将不起作用。相反,ctrl-s
将用于退出容器。您可以传递任何键,例如(ctrl-*)