3

I have a systemd service file that is running a Node.js app. The service seems to run fine, but when I stop the service, using systemctl stop train the service enters 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 that the Node.js app is returning a status code that systemd thinks is a failure. I am not sure if I need to make my Node.js app return a different status code, if that's possible. Or, if I need to modify the systemd service file to somehow act differently.

In case it will help, the deployments 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 the help!

Jonathan
  • 5,495
  • 4
  • 38
  • 53
  • > `Main PID: 25706 (code=exited, status=143)` does appear to be exiting non zero. What does it return when you send SIGTERM manually? http://www.freedesktop.org/software/systemd/man/systemd.kill.html – David Souther Aug 04 '14 at 11:37

2 Answers2

7

By default, when killed with SIGINT, node.js exits with a status code 143. That is 128+SIGTERM. This is expected behavior. From the doc:

SIGTERM and SIGINT have default handlers on non-Windows platforms that resets the terminal mode before exiting with code 128 + signal number. If one of these signals has a listener installed, its default behaviour will be removed (node will no longer exit).

If you want to exit gracefully, you will have 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)
});
Sylvain Leroux
  • 50,096
  • 7
  • 103
  • 125
2

You can specify your custom legal exit status in service unit file: SuccessExitStatus=143

kairius
  • 395
  • 6
  • 10