当我的Dockerfile以
CMD node .
Docker使用命令/bin/sh-c"节点."来运行该容器。
而不是简单的节点。
(我知道,我可以用CMD["节点", "."]
)。
我认为这种行为实际上很好,因为它意味着容器中的
PID1
是/bin/sh
,而不是我简单的节点脚本。
如果我正确理解
PID1
负责收获孤儿僵尸进程,我真的不想对此负责...所以如果/bin/sh
可以做到这一点,那就太好了。(我实际上认为这是docker重写我的CMD
的原因)。
问题是,当我发送一个
SIGTERM
到容器(以/bin/sh-c"节点"开始。),通过
docker-作曲家停止
或docker-作曲家杀死-s SIGTERM
,信号没有到达我的节点
进程,因此在10秒的宽限期后,它每次都被强制杀死。不漂亮。
有没有办法让某人管理我的僵尸,让我的节点实例接收docker发送的信号?
我的PID1问题解决方案:
Dockerfile以以下内容结束:
ENTRYPOINT ["/bin/bash", "-c"]
或者将ENTRYPOINT完全从Dockerfile中删除。默认值为/bin/sh-c
。
比我运行这个外壳脚本,它具有节点
的文件名,并且具有chmod x
:
#!/bin/bash
docker run --rm -it -p 8083:80 -v $HOME/node/work/:/root/node/:rw node_node "echo pid1 > /dev/null && node $@"
诀窍是回声pid1
echo
将捕获PID1并将输出发送到/dev/null
。
例如./node-v
将在运行的容器中返回Node.js的版本。
使用/node/root/node/hello world.js
命令运行Web服务器时,CTRL C将再次工作。
这是我的DockerizedNode.js开发环境。
编辑:
完全疯狂的想法,但是将这个名为bash脚本的节点
添加到$PATH。所以在主机上,您可以键入节点-v
而不是./节点-v
。你在Docker容器中运行节点,它看起来完全像是安装在主机上的。:)
有一些工具可以解决这个问题:
我认为如果你只有一个进程,你所需要做的就是用一个信号处理程序显式处理信号,而bash对你没有用。
使用[“node”,“]
语法,您可以使用https://nodejs.org/api/process.html#process_signal_events 让它在一个学期内退出。我相信这就足够了。
或者使用bash脚本,您可以使用陷阱"退出0"TERM
您也可以使用像http://skarnet.org/software/s6/这样的流程主管
我认为您必须了解ENTRYPOINT
和CMD
的角色,并在Dockerfile
中使用ENTRYPOINT
(exec表单)方式。
ENTRYPOINT
,指定容器的起始可执行文件,是Docker容器的核心部分。每个容器都必须有一个入口点来决定从何处开始。默认情况下,该值为/bin/bash-c
。此外,CMD
设置的所有内容都将作为参数附加到ENTRYPOINT
。
因此,如果您未能在Dockerfile
中指定ENTRYPOINT
,那么实际的入口点将是/bin/bash-c{your_command_in_CMD}
,不幸的是,它不会传递信号。
ENTRYPOINT
有两种形式:exec形式和shell形式
正如Docker参考资料所指出的:建议使用exec表单,而shell表单的缺点是命令由/bin/bash-c
执行,这可能无法很好地处理信号:
shell表单阻止使用任何CMD
或run
命令行参数,但有一个缺点,即您的ENTRYPOINT
将作为/bin/sh-c
的子命令启动传递信号。这意味着可执行文件将不是容器的PID 1
-并且不会接收Unix信号-因此您的可执行文件将不会从docker停止接收
SIGTERM
问题内容: 我正在使用以下命令构建新的Docker映像: 但是,它失败并显示以下错误: 这似乎在我的本地计算机(Mac OSX)上运行良好,但是当我尝试在Linux CentOS 7计算机上构建它时,它失败了。 问题答案: 最后,我们升级了项目以使用此Docker Maven插件:https : //github.com/fabric8io/fabric8-maven- plugin 。到目前为止
我正在从Bash脚本启动一个名为 的Java代码。Bash 脚本启动 Java 代码,然后运行 Java 代码。在Java程序结束时,我想发送一个信号回到Bash脚本以终止。请记住,Bash 脚本在 PID = 1 的情况下运行。我必须杀死PID 1过程。 我设置了bash脚本,使其在无限循环中运行,并< code >等待终止信号: 我正在使用Docker实例,信号是< code>sigterm。
我在跟踪stackoverflow的帖子 我应该以什么顺序向正常关闭进程发送信号? 并遇到了以下声明。请帮助我理解我以粗体标记的部分。[在答案中找到3票] 守护进程有时使用SIGHUP重新启动或重新加载配置的原因是守护进程从任何控制终端分离,因此永远不会接收SIGTERM,因此该信号被视为“释放”供一般使用。
按预期更正代码:从多处理导入池导入信号导入时间导入操作系统 ================================================== 我发现了问题,当我使用map函数时,主func被阻塞,只有map函数被funish时才会调用信号处理程序。所以,使用"map_async"函数来解决这个问题要好得多。 以下是我的发现: 纯用C语言实现的长时间运行的计算(例如对大量文本进行
这是我的Dockerfile的内容。 当我运行Dockerfile来构建docker映像时,我得到以下错误: /bin/sh:1:sudo:未找到 你能帮我解决上面的错误吗?
问题内容: 我正在创建节点命令行界面。它是全局安装的,并使用bin文件执行。 我计划在正在处理的文件的根目录下打开一个命令窗口,然后运行命令,但是由于返回节点包的目录,我无法确定当前的工作目录。最初,我假设由于代码是使用批处理文件作为包装器执行的(这就是bin文件可以在开始时没有节点的情况下执行的方式),所以这是不可能的,但是coffee- script可以做到这一点。我看了看咖啡脚本的源代码,但