nodejs / docker-node

Official Docker Image for Node.js :whale: :turtle: :rocket:
https://hub.docker.com/_/node/
MIT License
8.13k stars 1.95k forks source link

docker stop not triggering shutdown signal [v20] #2029

Open RRoohhiitt opened 4 months ago

RRoohhiitt commented 4 months ago

Environment

Expected Behavior

docker stop command should trigger SIGTERM signal

Current Behavior

For node:18.16.1-alpine3.18 and below the SIGTERM is received. But all above versions [I tried node:20.11.0-alpine3.18] its not received. Used command with init.

Steps to Reproduce

For both the version follow below steps

1) Nodejs

var http = require("http");
http.createServer(function (request, response) {
  // Send the HTTP header   
  // HTTP Status: 200 : OK  
  // Content Type: text/plain  
  response.writeHead(200, { 'Content-Type': 'text/plain' });
  // Send the response body as "Hello World"  
  response.end('Hello World\n');
}).listen(8081);
// Console will print the message  
console.log('Server running at http://127.0.0.1:8081/');

process.on('SIGTERM', () => {
  console.log('Received SIGTERM signal. Shutting down gracefully...');
  console.log('Server closed. Exiting...');
  process.exit(0);
});

2) Dockerfile

FROM node:20.11.0-alpine3.18
# FROM node:18.16.1-alpine3.18

# Copy the application's code to the container
COPY . /app

# Set the working directory
WORKDIR /app

# Install the application's dependencies
RUN npm install

# Expose port 8181
EXPOSE 8101

# Start the application
CMD ["npm", "start"]

3) Use below command to run

docker build -t nodeversiontest .
docker run -e NODE_ENV=test --privileged --name nodeversiontest -it --init -p 8081:8081 nodeversiontest:latest

4) docker stop

Additional Information

Steps and commands followed along with its output

NODE VERSION 18.16.1


1) apple@MacBook nodejs % docker build -t nodeversiontest .                                      
[+] Building 0.0s (9/9) FINISHED                                                                                                                                                      docker:default
 => [internal] load .dockerignore                                                                                                                                                               0.0s
 => => transferring context: 2B                                                                                                                                                                 0.0s
 => [internal] load build definition from Dockerfile                                                                                                                                            0.0s
 => => transferring dockerfile: 376B                                                                                                                                                            0.0s
 => [internal] load metadata for docker.io/library/node:18.16.1-alpine3.18                                                                                                                      0.0s
 .
 .
 .
 .                                                                                                          0.0s
 => => naming to docker.io/library/nodeversiontest  

2) apple@MacBook nodejs % docker run -e NODE_ENV=test --privileged --name nodeversiontest -it --init -p 8081:8081 nodeversiontest:latest

> nodejs@1.0.0 start
> node index.js

Server running at http://127.0.0.1:8081/

2) apple@MacBook nodejs % docker stop nodeversiontest
nodeversiontest

3) docker logs nodeversiontest
> nodejs@1.0.0 start
> node index.js

Server running at http://127.0.0.1:8081/
Received SIGTERM signal. Shutting down gracefully...
Server closed. Exiting...
npm notice 
npm notice New major version of npm available! 9.5.1 -> 10.4.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.4.0
npm notice Run npm install -g npm@10.4.0 to update!
npm notice 

4) apple@MacBook nodejs % docker inspect nodeversiontest
[
    {
        "Id": "2215c9b80868d22730cc66e37b41992e38c6f18dbfca3b3a3cbdde7f2da6953c",
        "Created": "2024-02-06T10:09:51.269367737Z",
        "Path": "docker-entrypoint.sh",
        "Args": [
            "npm",
            "start"
        ],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,  ----------
            "Error": "",
            "StartedAt": "2024-02-06T10:09:51.551227362Z",
            "FinishedAt": "2024-02-06T10:09:58.927703991Z"
        }...

NODE VERSION 20

1) apple@MacBook nodejs % docker build -t nodeversiontest .                                                                        
[+] Building 16.4s (10/10) FINISHED                                                                                                                                                       docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                                0.0s
 => => transferring dockerfile: 376B                                                                                                                                                                0.0s
 => [internal] load .dockerignore                                                                                                                                                                   0.0s
 => => transferring context: 2B                                                                                                                                                                     0.0s
 => [internal] load metadata for docker.io/library/node:20.11.0-alpine3.18                                                                                                                         15.5s
 .
 .
 .
 .                                                                                                    0.0s
 => => naming to docker.io/library/nodeversiontest    

2) apple@MacBook nodejs % docker run -e NODE_ENV=test --privileged --name nodeversiontest -it --init -p 8081:8081 nodeversiontest:latest

> nodejs@1.0.0 start
> node index.js

Server running at http://127.0.0.1:8081/

2) apple@MacBook nodejs % docker stop nodeversiontest
nodeversiontest

3) docker logs nodeversiontest (nothing is logged)
> nodejs@1.0.0 start
> node index.js

Server running at http://127.0.0.1:8081/

4) apple@MacBook test_Instarem % docker inspect nodeversiontest
[
    {
        "Id": "d116e6407e2a6501547f9601fe487af2ca1fab61f2e5a5b38e70d7cba32d44f3",
        "Created": "2024-02-06T10:13:21.922213296Z",
        "Path": "docker-entrypoint.sh",
        "Args": [
            "npm",
            "start"
        ],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 137, ---------- closed with code 137
            "Error": "",
            "StartedAt": "2024-02-06T10:13:22.254023546Z",
            "FinishedAt": "2024-02-06T10:13:51.121153143Z"
        }...

Please see points 3 and 4 for both the outputs above. For v20 it does not log the signal and gets forcefully shutdown with exit code 137 For v18 it logs the signal and the application closes with the expected exit code.

yosifkit commented 4 months ago

That looks like https://github.com/npm/cli/issues/6684#issuecomment-1932473284; so, the fix is to update npm to at least 10.3.0. I verified that npm start failed to forward the signals (and node server.js worked), but if I upgraded npm, then npm start worked again.