你好,
在 Ubuntu 13.04 上运行 docker 0.6.7。
我构建了一个容器,其 CMD 执行 uwsgi 进程(也尝试过其他可执行文件)。 我在没有分离的情况下运行,并且 sigproxy 是 True。
按 Ctrl-C 似乎对正在运行的容器没有影响,离开或杀死它的唯一方法是使用docker kill
和docker stop
...
这是一个已知的问题?
从 docker 0.6.5 开始,您可以将-t
到docker run
命令,这将附加一个伪 TTY。 然后您可以键入Control-C
以从容器中分离而不终止它。
如果您使用-t
和-i
那么Control-C
将终止容器。 当-i
与-t
一起使用时,您必须使用Control-P Control-Q
来分离而不终止。
测试 1:
$ ID=$(sudo docker run -t -d ubuntu /usr/bin/top -b)
$ sudo docker attach $ID
Control-C
$ sudo docker ps
容器仍被列出。
测试 2:
$ ID=$(sudo docker run -t -i -d ubuntu /usr/bin/top -b)
$ sudo docker attach $ID
Control-C
$ sudo docker ps
容器不存在(它已被终止)。 如果您在第二个示例中键入Control-P Control-Q
而不是Control-C
,容器仍将运行。
修复 Hello World 守护程序示例文档的拉取请求在这里:
https://github.com/dotcloud/docker/pull/2845
我不知道你在哪里看到了在这个例子之外对Control-C
的推荐。 如果您在其他地方看到此参考资料,能否请您提交一个新的拉取请求来修复您参考的文档?
您可能还会发现此邮件列表主题很有帮助。
@lhazlewood好吧,-t -d 可以让您在
$ ID=$(docker run -d ubuntu bash -c "while true; do echo foo; sleep 5; done")
$ docker attach $ID
在这种情况下 ctrl-C 什么也不做。 我希望它会终止“docker attach”进程(而不是容器)。
如果守护进程不是用 -t 启动的,我认为 docker attach 应该默认为 -sig-proxy=false
据我所知,您需要-t
和-i
才能让 Ctrl-C 按预期工作......
@vmalloc这取决于您的期望。 我希望能够使用 ctrl-c 与“docker attach”分离,而不是杀死守护进程。 如果不手动指定 -sig-proxy=false,目前这是不可能的。 如果您不小心这样做,唯一的出路是从另一个终端终止 docker attach 进程。
啊,抱歉上面有点糊涂了。 如果您运行“docker run -d -t”并且docker attach,那么ctrl-c _does_ detach,而不是杀死守护进程。 问题是,如果你忘记了 -t,然后使用 docker attach 你最终会得到一些你无法分离的东西,除非从不同的终端杀死它。
@alexlarsson是的,我上面展示的两个测试用例显示了带和不带-i
会发生什么。
是的,我遇到了同样的问题。 一种简单的重现方法是docker run busybox sleep 60
然后按 CTRL-C 即可。 在 60 秒结束之前,该命令不会终止或分离。 我希望 CTRL-C 向 sleep 命令发送一个 SIGTERM,这应该会停止 docker 实例。
另见#2855
要让 ctrl+c 停止容器,您必须使用 -it
要从容器中分离,您应该使用 ctrl+pq
关闭。
为什么这被关闭了? 你能解释一下原因吗?
我问是因为很明显社区的大多数人不想要当前的默认行为。
另请注意,在 VirtualBox 中运行 Ubuntu 的 Mac OS X 上,ctrl+pq _不起作用_。
@lhazlewood因为问题不在于 ctrl+pq,它是关于使用 ctrl-c 退出附加,这是不支持的,因为“附加”实际上是将您附加到正在运行的进程中,应该是预期的行为。
如果你只想要 stdout+stderr 流,你应该使用docker logs
不附加。
我认为这是一个培训问题,而不是 Docker 问题。
如果我们想讨论更改 ctrl-pq,并且我知道我已经看到其他问题,那很好。
我不确定我们现在可以改变它。
我们讨论过为它引入一个可配置的命令,但它是在服务器端实现的,并不理想,在客户端实现它很困难。
我以最友好的语气写下这一切,我生性简洁,对此感到抱歉。
我对这一切感到非常困惑。
在 shell 提示符下的默认行为是 ^C 终止正在运行的前台进程。 如果不存在这样的进程,它就什么也不做,除了可能显示一个新的提示。 ^D 另一方面,在不停止机器的情况下退出 shell。 这就是我所期望的,因为这就是其他人所做的。
那么,为什么 Docker 的做法不同呢? 为什么我会读到这个奇怪的讨论? 我错过了什么吗?
@rolkar因为在这种情况下有两个前台进程。
您在容器和 docker 客户端中附加的进程。
我个人认为这应该与 SSH 的行为方式大致相同,但转义序列不同。
仅供参考 SSH 的转义序列是<enter>~.
还是不明白。 为什么 Ctrl-C 不发送 SIGINT?
@Vanuan - 因为该进程在
是的,我想通了。 Docker 实际上会发送 SIGINT,但内核会忽略它,因为进程 ID 是 1。而且由于该进程没有自己的 SIGINT 处理程序,所以什么也不会发生。
内核不会忽略它,进程会。
@cpuguy83
所以你是说如果 pid 不是 1,SIGINT 被发送到父进程?
@Vanuan信号始终发送到您指定的进程,但某些进程在 pid 1 时不会加载信号处理程序,因此信号会被忽略。
杀死它的唯一方法是kill -9
,在这种情况下内核终止进程而不是进程终止自身。
似乎不是真的:
// main.c
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void catch_interrupt(int sig) {
printf("Interrupting...\n");
}
int main() {
signal(SIGINT, catch_interrupt);
sleep(10);
return 0;
}
$ docker run -it --rm -v `pwd`:/src -w /src iron/gcc:dev gcc main.c -o main
$ docker run -it --rm -v `pwd`:/src -w /src iron/gcc:dev ./main
^CInterrupting...
注释掉signal
相同设置:
$ docker run -it --rm -v `pwd`:/src -w /src iron/gcc:dev ./main
^C^C^C^C^C
# nothing happens
如您所见,信号处理程序已加载。 即使 PID 仍然是“1”,它也会响应 Ctrl-C 并终止(虽然我们没有要求它终止,我们只是处理了它)。 但是当没有注册信号处理程序时,它不会响应 Ctrl-C 并且没有任何反应。
@Vanuan是的,这正是我所说的。
信号仍然发送到程序,程序只是不响应它。
我提到了这部分:
某些进程在 pid 1 时不加载信号处理程序
是不是还有别的意思? 信号处理程序总是在注册时加载。
但是,如果 pid = 1 AND 信号处理程序未注册,则似乎有一些默认信号处理程序不会加载。 这是你的意思吗?
@Vanuan正是。
我仍然对此感到困惑。 示例运行:
docker run -i $IMAGE
ping google.com
PING google.com (216.58.217.46) 56(84) bytes of data.
64 bytes from 216.58.217.46: icmp_seq=1 ttl=61 time=31.5 ms
^C64 bytes from 216.58.217.46: icmp_seq=1 ttl=61 time=31.5 ms
^C^C^C^C^C^C^C^C64 bytes from 216.58.217.46: icmp_seq=1 ttl=61 time=31.5 ms
因此 ctrl+c 不会将 SIGINT 发送到 docker 进程或 ping 进程。 docker stop
我唯一的选择吗? (ctrl+p、ctrl+c 也不起作用。我在 OSX 上)
@johshoff这取决于图像如何启动ping
。
它是否在/bin/sh
内运行? 如果是这样,信号被发送到/bin/sh
,它在作为 pid 1 运行时忽略信号。
谢谢, @cpuguy83 ,这使它更清楚。 ping
确实在/bin/sh
下运行。
它是否在 /bin/sh 中运行? 如果是这样,信号将发送到 /bin/sh,它在作为 pid 1 运行时忽略信号。
不,/bin/sh 不会忽略 Ctrl-C。 Ping 也没有忽略它。 这里的问题是缺少-t
标志:
docker run -i $IMAGE
应该是
docker run -it $IMAGE
例如:
docker run --rm -it alpine sh -c "ping -c 4 google.com"
对比
docker run --rm -i alpine sh -c "ping -c 4 google.com"
对比
docker run --rm -ti alpine ping -c 4 google.com
对比
docker run --rm -i alpine ping -c 4 google.com
我同意@cpuguy83 的观点,因为我在这里看不到/bin/sh
的事实。 对此非常简单的解决方案是使用
sh -c "exec ping google.com"
用 ping 进程替换 shell 进程
代替
sh -c "ping google.com"
当使用sh -c "exec ping google.com"
,信号 (Ctrl-C) 被发送到ping
而不是sh
。 并且 ping 以 pid 1 运行时不会忽略此信号
@jarl-dk
并且 ping 以 pid 1 运行时不会忽略此信号
如果没有,为什么不直接使用 ping 呢?
您可以告诉 node.js 处理信号:
// For Docker
process.on('SIGINT', function() { console.log('Caught Ctrl+C...'); process.exit(); }); // Ctrl+C
process.on('SIGTERM', function() { console.log('Caught kill...'); process.exit(); }); // docker stop
我已经用 ping 命令启动了容器,当我连接容器时,即使我按下 ctrl+c,Ping 进程仍然继续运行
如何停止 ping In 容器?
使用的步骤:
docker run --name centos-linux -d centos /bin/sh -c "while true; do ping 8.8.8.8; done"
docker 附加 centos-linux
很抱歉,但我不明白为什么有时无法从附加的容器中分离。 我知道,如果以 pid=1 运行,某些进程可能会忽略 SIGINT,但在这种情况下,必须有一种方法可以从同一个终端会话中杀死或分离附加的容器。
例如,当使用 eboraas/apache 映像时,该映像通过在 Dockerfile 中以 exec 形式使用 CMD 命令在前台执行 apache:
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
当我从这个图像启动容器docker run -p 80:80 -d eboraas/apache
,重视它与docker attach
或者如果我不小心错过了-d
标志我从容器要么分离无变化或从同一个终端会话停止/终止容器。
要停止容器,我必须使用另一个终端会话来执行docker stop
。 即使我使用-i
标志启动容器,ctrl+c、ctrl+d 和 ctrl+pq 也无效。
我在 Mac OS X 下使用 Docker for Mac。
把它放到你的 alpine 3.4 Dockerfile 中:
RUN apk add tini
ENTRYPOINT ["/sbin/tini", "--"]
你很高兴去。
1 年后,我们仍然不能 Ctrl+C 一个 docker 容器
@sebdelvalle你可以。 只是不是所有的 docker 容器都响应 Ctrl+C。 如果您创建了在 docker 容器中运行的软件,则您有责任正确处理 Ctrl+C。 如果您不按 Ctrl+C 关闭软件,则没有人会为您关闭。
你看,当你在没有 docker 的情况下运行你的软件时,你有一个终端和初始化系统,它可以处理 Ctrl+C。 当您在 docker 中运行它时,您没有任何终端。 您的软件成为系统的入口点。 这就像直接从重启启动你的软件。
我的 node.js 应用程序也有同样的问题......我用
/**
* Does what it says :-)
*/
function endProcess(reason) {
// eslint-disable-next-line no-console
console.log(`Quitting... Reason: ${reason}`);
process.exit();
}
/**
* Adds hooks for Docker CTRL-C and Stop
*/
function dockerConfig() {
[
'SIGINT',
'SIGTERM'
].forEach((signal) => {
process.on(signal, () => {
endProcess(signal);
});
});
}
module.exports = dockerConfig;
哪个命令停止泊坞窗?
ctrl + C 不要停止
@romenigld docker在进程停止时停止
exec 为我工作。
例如,运行 uwsgi,ctrl+c 不起作用:
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 1)
spawned uWSGI worker 1 (pid: 6, cores: 1)
spawned uWSGI worker 2 (pid: 7, cores: 1)
spawned uWSGI worker 3 (pid: 8, cores: 1)
spawned uWSGI worker 4 (pid: 9, cores: 1)
spawned uWSGI worker 5 (pid: 10, cores: 1)
^C^C^C^C^C^C^C^C^C
但是然后运行 exec uwsgi,ctrl+c 被显式接收:
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 1)
spawned uWSGI worker 1 (pid: 6, cores: 1)
spawned uWSGI worker 2 (pid: 7, cores: 1)
spawned uWSGI worker 3 (pid: 8, cores: 1)
spawned uWSGI worker 4 (pid: 9, cores: 1)
spawned uWSGI worker 5 (pid: 10, cores: 1)
^CSIGINT/SIGQUIT received...killing workers...
@montanaflynn它能够从终端打开另一个选项卡并输入: docker stop <container_id>
另一种方式,如果你使用像@alvarow这样的节点,你可以使用npm start
和package.json
的规则,npm 将在ctrl-c
上关闭:
像这样:
{
"name": "prom-koa-example",
"version": "1.0.0",
"description": "Expose prometheus metrics in koa",
"main": "index.js",
"scripts": {
"start": "node index.js",
},
"dependencies": {
"koa": "^1.2.0",
"koa-router": "^5.4.0",
"prom-client": "^9.1.1"
}
}
我使用了一个 shell 脚本,因为我的命令docker-php-entrypoint apache2-foreground
没有在 Control+C 上退出。
docker-php-entrypoint apache2-foreground &
apache_pid="$!"
kill_apache() {
kill "$apache_pid"
}
#trap 'kill_apache' INT
wait "$apache_pid"
这里, docker-php-entrypoint apache2-foreground
只是一个不响应 Control+C 的命令示例。 如果您有其他命令没有响应,您可以尝试将其替换为您的命令,然后查看脚本是否响应 Control+C。
您正在使用apache2-foreground
启动 apache,然后使用&
对其进行守护?
这是我对它的理解。
在编写 Dockerfile 时,有两个与启动容器进程相关的命令: ENTRYPOINT
和CMD
。
ENTRYPOINT
定义了要启动的可执行文件,而CMD
定义了要传递给可执行文件的参数。 默认情况下, ENTRYPOINT
等于/bin/sh
。
因此,当 Dockerfile 没有ENTRYPOINT
而只有CMD "node src/index.js"
,容器中实际运行的进程类似于: /bin/sh -c "node src/index.js"
现在由于某种原因我不完全理解,当sh
收到一个 SIGINT 时,无论是通过docker stop
还是ctrl-c
中的docker run -it ...
,它都不会将此信号转发到它启动的进程(在这种情况下node src/index.js
)。
因此,定义 Dockerfile 以运行 nodejs 容器的正确方法是:
FROM node:8
# some stuff...
ENTRYPOINT ["node"]
CMD ["src/index.js"]
其中src/index.js
具有 SIGINT 的信号处理程序。
现在, docker stop <container>
完美运行。
这可以很容易地复制到其他类型的过程中,所以我希望它有所帮助 :smiley:
现在由于某种原因我不完全理解,当 sh 收到 SIGINT 时,无论是通过 docker stop 还是 ctrl-c 在 docker run -it ...,它都不会将此信号转发到它启动的进程
正确的; 以pid 1
运行的进程通常与以不同 pid 运行的同一进程不同。 ( pid 1
是“特殊的”,因为它是计算机的(在这种情况下:容器的)主进程)。 当以 pid 1 运行时, sh
不会转发信号,因此它的子进程不会被杀死。
直接通过ENTRYPOINT
/ CMD
指定进程是一种选择; 另一个选项是exec
要在入口点脚本末尾运行的进程。
比如官方的httpd
镜像使用httpd-foreground
包装脚本来执行一些初始化任务,但是最后一步是exec
容器的主进程( httpd
); https://github.com/docker-library/httpd/blob/53654452889ae3af537eef2dbb981ccac6fb907f/2.2/httpd-foreground#L1 -L7
使用exec
使 shell 本身退出,并运行您指定的进程(从而使其成为容器内的pid 1
)
引用我上面的建议:
RUN apk add tini
ENTRYPOINT ["/sbin/tini", "--"]
现在您不在乎是否在 CMD 中使用sh
。
如果您不需要sh
,请不要运行它; 使用exec
可以避免在容器内运行一个额外的进程,这可能会有所帮助。
(另外,使用docker run --init
会自动在你的容器中注入tini
,无需添加)
凉爽的! 是否有相应的 compose 选项?
看起来没有: https :
所以对于 swarm 来说,如果你使用 docker-compose 你仍然需要tini
。
可以默认启用 init 选项(通过设置守护程序选项); 然后所有容器,包括那些作为服务的一部分启动的容器都得到--init
。 正在进行 PR https://github.com/docker/cli/pull/479
无法在我的 Ubuntu 17.04 操作系统中使用 CTRL+P、CTRL+Q 分离。 啊啊啊
1 年后,我们仍然不能 Ctrl+C 一个 docker 容器
现在2年了🎂
在 MacOSX 上仍然出现错误。
@felipekm没有帮助:您遇到了什么问题? 你读过这个线程吗?
是的,我有@thaJeztah ,我只是想杀死一个由docker run -ti <image_id>
初始化的进程。
@felipekm在另一个终端类型docker ps
然后docker stop <container_id>
如果您希望Ctrl+C
工作,您需要更改您的 docker 容器以响应SIGINT
。
更新:这里已经回答了https://github.com/moby/moby/issues/37200
真实世界用例:运行 Docker 容器并在 CI 中进行测试:
docker run -ti my-image my-test-script
CI 不支持 TTY 所以我得到:
the input device is not a TTY
stdin: is not a tty
ERROR: Job failed: exit status 1
当我没有 TTY 时,如何将 SIGTERM 传播到容器入口点?
我想要的进程树:
bash
docker run -ti my-image my-test-script
CI runner 将向 bash 脚本发送一个 SIGTERM,该脚本将传播到 docker run,但由于没有 TTY 支持,它无法使用 -ti 运行。
这适用于我的终端。
@aalexgabi这是我在 CI (jenkins) 上使用的:
# Fix docker signal proxy issue without tty
function docker() {
case "$1" in
run)
shift
if [ -t 1 ]; then # have tty
command docker run --init -it "$@"
else
id=`command docker run -d --init "$@"`
trap "command docker kill $id" INT TERM
command docker wait $id
fi
;;
*)
command docker "$@"
esac
}
# export to sub-shell
export -f docker
@felipekm尝试在启动容器时添加--init
。 这会将Tini作为 PID 1 启动,Tini 将确保您的应用程序获得 SIGINT(而不是被 /bin/sh 拦截)。
更多细节在上面的线程中。
总之:
docker run -it
是不够的。 如果它不是您的程序,则特别有问题……例如,另一个程序以有限的方式解释您的程序时就是这种情况。ENTRYPOINT ["/sbin/tini", "--"]
设为入口点...而不是您的应用程序。docker run -it --init
它将解决您所有的问题。@guiambros非常有用,它在我的别名中。
也适用于群模式:
相应的撰写更改最近已合并,因此在下一个版本中,您将能够执行以下操作:
version: '3.7'
services:
myservice:
image: myimage
init: true
最后,您不必为了添加tini
而修改图像,以便在不响应 SIGTERM 时不会杀死您的容器(退出代码 137)。 特别适用于数据库以防止数据丢失。
最后,您不必为了添加 tini 而修改图像,以便在不响应 SIGTERM 时不会杀死您的容器(退出代码 137)。 特别适用于数据库以防止数据丢失。
只需将其添加为附加信息(其中一些已在之前的评论中提到);
虽然使用--init
(或在您的图像中添加tini
)可以快速帮助处理无法正确处理信号的图像,但请确保您没有“掩盖”实际问题与图像。
Tini 提供以下功能;
如果您知道在容器内运行的进程是一个“坏演员”,并且不处理收割,那么使用--init
绝对是让您前进的好选择。 但是请注意,您实际上遇到了错误; 请务必向您在容器中运行的软件的维护者/发布者报告问题:也许他们不知道这种情况,并且可以修复它。
如果您因为2.
--init
而使用
例如; 以下CMD
将启动一个 shell( /bin/sh
或/bin/bash
,具体取决于图像),其中启动mysqld
;
CMD /usr/sbin/mysqld
正因为如此, /bin/sh
(不是mysqld
)成为了容器的主进程(PID-1),任何发送到容器的信号都会由/bin/sh
(和没有转发到mysqld
)。 使用--init
将“解决”这种情况( /bin/sh
现在作为 PID-2 运行,而mysqld
作为 PID-3 运行),但仍然在容器。
要使容器的进程在_无_shell 的情况下运行,请使用 JSON ("exec" form) 。 比如下面是mysql官方镜像的CMD
;
CMD ["mysqld"]
但是如果你需要在启动容器时(在运行容器的主进程之前)运行一些命令,比如设置权限,或者在容器第一次运行时做一些设置呢?
这些步骤可以在entrypoint-script 中完成。 入口点脚本可以运行一个 shell,执行初始化(例如,参见官方 WordPress 入口点脚本中的exec
切换到容器的主进程。
使用exec
,当前进程会被另一个进程替换,因此在入口点脚本末尾使用exec
时,容器的主进程将作为 PID-1 运行,而不是运行壳内; 这是WordPress 入口点脚本的
exec "$@"
Dockerfile 同时使用ENTRYPOINT
和CMD
,在这种情况下, CMD
用作ENTRYPOINT
;
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["apache2-foreground"]
exec "$@"
将因此默认为exec apache2-foreground
,但将替换为用于启动容器的命令(例如docker run mysql echo "hello"
,将运行入口点脚本,然后exec echo "hello"
)
TL; 博士; --init
选项可以安全使用,并且可能对您的情况有所帮助,但请确保您没有缩小图像中的实际问题:微笑:
更新:这里已经回答了https://github.com/moby/moby/issues/37200
@rayfoss @thaJeztah当您没有 TTY 时, --init
和-ti
再次不是解决方案,请参阅 #37200
我希望docker run myScriptImage
与运行./myScript
完全相同,只是它在隔离和受控的环境中运行。 我希望 Ctrl-C 可以像“任何其他脚本”一样开箱即用。 如果在任何 bash 脚本中我可以用等效的docker run myEquivalentCommand
替换任何系统命令并使其工作方式与我在本地启动命令(stdin、stdout、stderr、退出代码、输入)相同,那将是理想的缓冲、输出缓冲、信号处理等)。
更新:这里已经回答了https://github.com/moby/moby/issues/37200
@tsl0922谢谢,但这就是我试图避免做的。 我觉得我可能正在执行一个名为wrap-docker-run-as-if-is-a-regular-program
的命令,它将使用 bash 陷阱处理所有这些,而不是在所有 ci 管道中复制粘贴该代码(大约有 30 个。)
@aalexgabi
--init 和 -ti 当您没有 TTY 时不是解决方案,请参阅 #37200
TTY 与能够发送或捕获信号无关。 请阅读我在您提到的那个问题线程中的消息。
一个问题:想知道官方图片使用的解决方案是什么......比如说nginx。 Nginx 容器可以在不处于分离模式时使用 SIGINT 终止。
@bidiu首先,它使用 exec 形式:
CMD ["nginx", "-g", "守护进程关闭;"]
其次,nginx 自己处理信号。
最后,它使用
STOPSIGNAL SIGTERM 以便当您以交互模式向 docker 发送 SIGINT 或运行 docker stop 容器时,它会发送 SIGTERM,该 SIGTERM 将由 nginx 处理以终止自身
你可以通过查看它的 Dockerfile 自己弄清楚:
https://github.com/nginxinc/docker-nginx/blob/master/mainline/alpine/Dockerfile
@Vanuan
啊哈,之前不知道STOPSIGNAL
指令,也不熟悉“exec form”以外的模式。 谢谢你的澄清😊
所以有shell形式和exec形式。 Shell 形式的用法如下:
CMD nginx
执行形式如下:
CMD ["nginx"]
在第一种情况下,shell 处理您的信号,在第二种情况下,nginx 进程
对于在无法使用 SIGINT 停止node
进程后来到这里的人们,我发现另一个问题对于理解这种行为也非常有帮助。
截至目前,使用 Windows 10,您需要在 git bash 中像这样运行
winpty docker run -it i<id>
最有用的评论
从 docker 0.6.5 开始,您可以将
-t
到docker run
命令,这将附加一个伪 TTY。 然后您可以键入Control-C
以从容器中分离而不终止它。如果您使用
-t
和-i
那么Control-C
将终止容器。 当-i
与-t
一起使用时,您必须使用Control-P Control-Q
来分离而不终止。测试 1:
容器仍被列出。
测试 2:
容器不存在(它已被终止)。 如果您在第二个示例中键入
Control-P Control-Q
而不是Control-C
,容器仍将运行。修复 Hello World 守护程序示例文档的拉取请求在这里:
https://github.com/dotcloud/docker/pull/2845
我不知道你在哪里看到了在这个例子之外对
Control-C
的推荐。 如果您在其他地方看到此参考资料,能否请您提交一个新的拉取请求来修复您参考的文档?您可能还会发现此邮件列表主题很有帮助。