docker-pm2
docker-pm2 copied to clipboard
Improve Graceful Shutdown
Our example about how to implement a serious graceful shutdown is too minimalist. It's good as example but it's not enough in production environments.
Some days ago I've found this amazing package made from @Tappi and @sindresorhus that enable us to implement a more rigid graceful shutdown.
This is an example of implementation:
const exitHook = require('async-exit-hook');
// Set this with the same value of 'kill_timeout'
exitHook.forceExitTimeout(1600);
// The exit callback.
// This will be always called before the server exits
exitHook(cb => {
server.close(() => {
db.stop(function(err) {
cb(); // When you have ended your cleanup operations
});
})
});
// Called after an uncaught exception.
// The exit callback will called after this.
exitHook.uncaughtExceptionHandler((err, cb) => {
// Log the error on the console
console.log(err);
cb();
});
// Called after an unhandled rejection.
// The exit callback will called after this.
exitHook.unhandledRejectionHandler((err, cb) => {
// Log the error on the console
console.log(err);
cb();
});
I think we should add a better example, maybe suggesting users to use the package mentioned before. But if we do so we should write something that explains why to use this package and how.
Any thoughts on this?
It also seems to have a dedicated hook for pm2 (I don't know if its right) https://github.com/Tapppi/async-exit-hook/blob/master/index.js#L96
Very interesting. We could enhance the exit handling via pmx directly. That's true that currently we recommend to catch the SIGINT handler only, a signal that is triggered by pm2 in case or restarts/stop/reload but not when an exception/unhandled rejection has been thrown.
var pmx = require('pmx');
pmx.exitHook(cb => {
server.close(() => {
db.stop(function(err) {
cb(); // When you have ended your cleanup operations
});
})
});
@simonepri @Unitech I'm pretty sure this requires pm2-runtime to be used as ENTRYPOINT, instead of CMD.
Currently, we are using CMD: https://github.com/keymetrics/docker-pm2/blob/master/tags/8/alpine/Dockerfile#L11
This matters because docker container only forward signals to PID 1. And, only ENTRYPOINT can be PID 1
Another option is to add tini.
Personally, I believe it's slightly better to prefer ENTRYPOINT - instead of the unnecessary extra shell