Dock stop does not work for node process

I want to be able to run node inside a docker stop <container> container, and then be able to run docker stop <container> . This should stop the SIGTERM container, not the timing, and make SIGKILL . Unfortunately, I seem to be missing out on something, and the information I found seems to contradict other bits.

Here is the docker test file:

 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"] 

Here is the test.js mentioned in the Docker file:

 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) }); 

I will build it like this:

 $ docker build -t test . 

I run it like this:

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

Then I run:

 $ docker stop test 

After that, SIGTERM does not seem to work, causing it to time out after 10 seconds and then die.

I found that if I ran the node task via sh -c , then I can kill it with ^C from the interactive container ( -it ), but I still can't get docker stop Work. This contradicts the comments I read saying sh does not transmit a signal, but may agree with the other comments I read saying PID 1 does not receive SIGTERM (since it started with sh , this will be PID 2).

The ultimate goal is to be able to run docker start -a ... in the upstart job and be able to stop the service and actually exit the container.

+6
source share
2 answers

Well, I figured out a workaround myself, which I would dare as an answer in the hope that this will help others. He doesn't fully answer why the signals didn't work before, but that gives me the behavior I want.

Using baseimage-docker seems to solve the problem. Here is what I did to get this working with the minimum test case above:

Keep test.js as is.

Modify the Dockerfile to look like this:

 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-docker includes an init process ( /sbin/my_init ), which processes other processes and processes zombie processes. It uses runit to oversee the service. Therefore, Dockerfile sets the my_init process as a command to start at boot and adds script /etc/service to run to pick it up.

run.sh script is simple:

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

Do not forget chmod +x run.sh !

By default, runit will automatically restart the service if it drops.

Following these steps (and create, start and stop, as before), the container correctly responds to requests for its completion, in a timely manner.

+2
source

I do not know if it is too late. But my way to do this is to catch SIGINT (interrupt signal in your javascript).

 var process = require('process') process.on('SIGINT', () => { console.info("Interrupted") process.exit(0) }) 

This should work when you press Ctrl + C

0
source

Source: https://habr.com/ru/post/981070/


All Articles