如何在终端/ gitbash / powershell / etc中的Ctrl + C上自动停止和删除Docker容器?

时间:2017-12-28 13:19:45

标签: docker

例如我运行

docker run --rm --name mycontainer -p 8080:8080 myrepo/myimage

然后我看到我的应用程序的输出,一切正常。然后我按 Ctrl + C 但容器仍在运行,我被迫明确停止并删除它:

docker rm -f <container_id>

甚至更糟:

docker stop <container_id>
docker rm <container_id>

有没有办法自动完成?如果没有,那就没关系。

PS:所有停止的容器仍保留在硬盘驱动器上的目的是什么?!

2 个答案:

答案 0 :(得分:1)

  

所有停止的容器仍保留在硬盘驱动器上的目的是什么?!

运行容器包括您运行的进程以及命名空间环境,以便在(网络,pid,文件系统等)内运行该进程。

已停止的容器具有容器特定的读/写文件系统层,运行容器时包含的任何配置(例如环境变量),以及使用json日志记录驱动程序时的日志(默认)。

删除容器会删除RW文件系统层,json日志和配置,这也会从已停止的容器列表中删除容器。这是一个永久性操作,因此不要删除您可能希望稍后检查或重新启动的容器。

  

我按 Ctrl + C 但容器仍在运行,我被迫明确停止并将其删除

首先,确保您运行的是当前版本的docker。我相信大约在1.13左右,他们将--rm选项的处理从客户端迁移到服务器。接下来,确保您的应用程序处理 Ctrl + C 命令。在shell脚本中,这将是SIGTERM的处理程序。您还需要以交互方式运行容器,以便将键盘输入发送到容器,即-it标志。完成所有这三个后,您应该看到容器自动清理:

docker run --rm -it --name mycontainer -p 8080:8080 myrepo/myimage

后跟 Ctrl + C -it会将SIGTERM传递给容器,然后该容器应停止进程,从而停止正在运行的容器。而--rm将导致容器被自动删除。

如果由于某种原因您无法让容器处理SIGTERM,那么您可以使用SIGKILL命令发送docker kill,该命令不会被应用程序捕获和忽略。

请注意,如果您在容器上运行docker stop并在停止之前看到10秒的延迟,那么您的应用程序将忽略SIGTERM。造成这种情况的一个常见原因是/bin/sh以pid 1运行。如果您处于信号用户模式,shell默认运行时会忽略此信号,假设您处于信号用户模式。

答案 1 :(得分:-1)

默认情况下,docker以pid 1的形式运行image命令.pid 1由内核特殊处理,因为它通常用于系统初始化进程。因此,CTRL+C / SIGTERM对pid 1无效。

实际的docker版本提供选项--init以运行最小的init系统(tini)作为pid 1.您的image命令以tini的子项运行。由于不再是pid 1,您的图像命令将再次接受CTRL+C

--init添加到您的示例命令中,您可以使用CTRL+C

停止
docker run --rm --init --name mycontainer -p 8080:8080 myrepo/myimage

在您的情况下不需要,只需要其他信息:您可以使用docker stop更改来自--stop-signal SIGNAL的信号,其中SIGNALkill -L显示的众多信号之一,例如SIGHUPSIGINT