Why is a systemd app running with a Node.js app showing a failure status when properly stopped?
I have a systemd service file that is running a Node.js application. The service is running fine, but when I stop the service using systemctl stop train
, the service goes into a failed state.
[root@localhost portaj]# systemctl stop train
[root@localhost portaj]# systemctl status train
train.service - Train Service
Loaded: loaded (/etc/systemd/system/train.service; enabled)
Active: failed (Result: exit-code) since Mon 2014-08-04 04:40:17 UTC; 1s ago
Process: 25706 ExecStart=/opt/node/bin/node /opt/train/src/server/start.js (code=exited, status=143)
Main PID: 25706 (code=exited, status=143)
Aug 04 04:33:39 localhost.localdomain train[25706]: Train Server listening on port 3000
Aug 04 04:40:17 localhost.localdomain systemd[1]: Stopping Train Service...
Aug 04 04:40:17 localhost.localdomain systemd[1]: train.service: main process exited, code=exit.../a
Aug 04 04:40:17 localhost.localdomain systemd[1]: Stopped Train Service.
Aug 04 04:40:17 localhost.localdomain systemd[1]: Unit train.service entered failed state.
My service file looks like this:
[Unit]
Description=Train Service
After=network.target
[Service]
Environment=PORT=4000
Environment=NODE_ENV=development
ExecStart=/opt/node/bin/node /opt/train/src/server/start.js
Restart=on-failure
SyslogIdentifier=train
[Install]
WantedBy=network.target
I suspect the Node.js application is returning a status code that systemd considers to be unsuccessful. I'm not sure what I need to do to get my Node.js app to return a different status code if possible. Or, if I need to modify the systemd service file to act differently somehow.
In case it helps, the deployment scripts are here: https://github.com/JonathanPorta/ansible-train
The actual Node.js app is here: https://github.com/JonathanPorta/train
Thanks in advance for your help!
source to share
By default, when killed with SIGINT
, node.js exits with a status of 143. This 128+SIGTERM
. This is expected behavior. From the doc:
SIGTERM and SIGINT have default handlers on non-Windows platforms that reset terminal mode to exit with code 128 + signal number. If a listener is set in one of these signals, its default behavior will be removed (node โโwill not exit anymore).
If you want to exit gracefully, you need to override the default signal handler :
process.on('SIGTERM', function() {
console.log('SIGTERM')
// do whatever to terminate properly
// at worst, just 'exit(0)'
process.exit(0)
});
process.on('SIGINT', function() {
console.log('SIGINT')
// do whatever to terminate properly
// at worst, just 'exit(0)'
process.exit(0)
});
source to share