2015-01-15 30 views
6

我希望能夠在碼頭集裝箱內運行節點,然後能夠運行docker stop <container>。這應該在SIGTERM上停止容器,而不是超時並執行SIGKILL。不幸的是,我似乎錯過了一些東西,我發現的信息似乎與其他的東西相矛盾。碼頭停止對節點進程不起作用

下面是測試Dockerfile:

FROM ubuntu:14.04 
RUN apt-get update && apt-get install -y curl 
RUN curl -sSL http://nodejs.org/dist/v0.11.14/node-v0.11.14-linux-x64.tar.gz | tar -xzf - 
ADD test.js/
ENTRYPOINT ["/node-v0.11.14-linux-x64/bin/node", "/test.js"] 

這裏是在Dockerfile提到的test.js

var http = require('http'); 

var server = http.createServer(function (req, res) { 
    console.log('exiting'); 
    process.exit(0); 
}).listen(3333, function (err) { 
    console.log('pid is ' + process.pid) 
}); 

我構建它,像這樣:

$ docker build -t test . 

我運行像這樣:

$ docker run --name test -p 3333:3333 -d test 

然後我運行:

$ docker stop test 

因此,那些SIGTERM顯然不工作,導致它以後超時10秒,然後死去。

我發現,如果我通過sh -c啓動節點任務,然後我可以^C從交互式(-it)容器殺死它,但我仍然不能得到docker stop工作。這與我所讀的sh沒有傳遞信號的評論相矛盾,但可能與我讀過的其他評論一致認爲PID 1沒有得到SIGTERM(因爲它是通過sh開始的,它將是PID 2)。

最終目標是能夠在暴發性的工作中運行docker start -a ...並能夠停止服務,並且它實際上退出容器。

回答

1

好吧,我想出了一個解決方法,我會冒昧作爲一個答案,希望它可以幫助其他人。它並沒有完全回答爲什麼信號之前沒有工作,但它確實給了我想要的行爲。

使用baseimage-docker似乎解決了這個問題。以下是我用上面的最小測試示例得到的結果:

保持test.js原樣。

修改Dockerfile到如下所示:

FROM phusion/baseimage:0.9.15 

# disable SSH 
RUN rm -rf /etc/service/sshd /etc/my_init.d/00_regen_ssh_host_keys.sh 

# install curl and node as before 
RUN apt-get update && apt-get install -y curl 
RUN curl -sSL http://nodejs.org/dist/v0.11.14/node-v0.11.14-linux-x64.tar.gz | tar -xzf - 

# the baseimage init process 
CMD ["/sbin/my_init"] 

# create a directory for the runit script and add it 
RUN mkdir /etc/service/app 
ADD run.sh /etc/service/app/run 

# install the application 
ADD test.js/

baseimage-搬運工包括一個初始化處理(/sbin/my_init),其處理開始的其它過程和處理zombie processes。它使用runit進行服務監督。因此,Dockerfile將my_init進程設置爲在啓動時運行的命令,併爲腳本添加腳本/etc/service以進行檢索。

run.sh腳本很簡單:

#!/bin/sh 
exec /node-v0.11.14-linux-x64/bin/node /test.js 

不要忘了chmod +x run.sh

默認情況下,runit會在服務關閉時自動重啓服務。

按照以下步驟(並像以前一樣構建,運行和停止),容器會及時響應關閉它的請求。