Skip to content

Instantly share code, notes, and snippets.

@pulkitsinghal
Last active September 20, 2017 04:17
Show Gist options
  • Save pulkitsinghal/a788b409fe37ba00dbbc1ab2250cfcb6 to your computer and use it in GitHub Desktop.
Save pulkitsinghal/a788b409fe37ba00dbbc1ab2250cfcb6 to your computer and use it in GitHub Desktop.
Why is my NodeJS process hanging in Docker?

Establish the directory structure

  • README.md
    • docker-compose.yml
    • worker/package.json
    • worker/src/utils.js
    • worker/src/sampleNodeProcess.js

Run the experiment

  • Terminal A:

    1. Install dependencies: docker-compose run worker npm install
    2. Run the sample nodejs process: docker-compose run worker node src/sampleNodeProcess
  • Terminal B:

    1. Find the name of the docker container which is runnign the process:
    $ docker ps -a
    CONTAINER ID   IMAGE   COMMAND                 CREATED        STATUS        PORTS  NAMES
    90ed79aa7ac5   node:7  "node src/sampleNo..."  8 seconds ago  Up 6 seconds         worker_run_12
    
    1. Send an interrupt to the appropriate container name: docker stop worker_run_12
  • Terminal A

    1. You should see that the process exited gracefully:
    trapSignals ... server started
    {"name":"sp-json-logger","hostname":"...","pid":1,"level":40,"application":"","program":"","language":"","log":{"message":"server stopped by SIGTERM"},"msg":"","time":"...","v":0}
    [WTF Node?] open handles:
    - File descriptors: (note: stdio always exists)
      - fd 1 (tty) (stdio)
      - fd 2 (tty) (stdio)
    - Servers:
      - <unknown address>
        - Listeners:
          - request: (anonymous) @ /apps/src/lib/trapSignals.js:8
    
version: '3.1'
services:
worker:
#restart: always
image: node:7
env_file:
- ./worker/.env
volumes:
- ./worker/src:/apps/src
- ./worker/node_modules:/apps/node_modules
- ./worker/package.json:/apps/package.json
working_dir: /apps
{
"license": "ISC",
"dependencies": {
"sp-json-logger": "1.0.9"
},
"devDependencies": {
"wtfnode": "0.5.4"
}
}
'use strict';
const wtfnode = require('wtfnode');
const logger = require('sp-json-logger');
var http = require('http');
var server = http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(3000, '0.0.0.0');
console.log('trapSignals ... server started');
const utils = require('../lib/utils');
var shutdown = function shutdown(signal, value) {
server.close(function () {
logger.warn( { log: { message: 'server stopped by ' + signal } } );
wtfnode.dump();
process.exit(128 + value);
});
};
utils.registerForGracefulShutdown(shutdown);
/**
* Idea came from https://medium.com/@gchudnov/trapping-signals-in-docker-containers-7a57fdda7d86
*
* @param {*} shutdown - the calling code user this method to control what actions to take as part of shutdown
*/
var registerForGracefulShutdown = function registerForGracefulShutdown(shutdown) {
var signals = {
'SIGINT': 2,
'SIGTERM': 15
};
Object.keys(signals).forEach(function (signal) {
process.on(signal, function () {
shutdown(signal, signals[signal]);
});
});
};
module.exports = {
registerForGracefulShutdown: registerForGracefulShutdown
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment