Geert-Jan
Geert-Jan

Reputation: 18895

How to only restart node process with PM2 if exit code != 0

I'm using pm2 to manage a node process. Currently, pm2 restarts the node process even if it finishes cleanly (with exit code 0). I don't want that to happen.

Instead I only want PM2 to restart the app when the node process exits with a code != 0.

How to do this?

The pm2 logs might be useful:

PM2        | App [xxx] with id [0] and pid [44797], exited with code [0] via signal [SIGINT]
PM2        | Starting execution sequence in -fork mode- for app name:xxx id:0
PM2        | App name:xxx id:0 online

EDIT:

Seems that starting process in cluster-mode works as I expect. I.e.: restarts only happen on exit-codes !=0.

Still starting in fork-mode gives the unexpected behavior as described above.

Upvotes: 12

Views: 8553

Answers (4)

Zack
Zack

Reputation: 1703

This is possible using the stop_exit_codes parameter.

See here: https://pm2.keymetrics.io/docs/usage/restart-strategies/

According to their docs:

CLI:

pm2 start app.js --stop-exit-codes 0

Via configuration file:

module.exports = [{
  script: 'app.js',
  stop_exit_codes: [0]
}]

Upvotes: 1

stoic_monk
stoic_monk

Reputation: 185

Late to this thread, but I believe pm2 support this now. Check out https://pm2.keymetrics.io/docs/usage/restart-strategies/ and the section "Skip Auto Restart For Specific Exit Codes"

Edit: Sorry, this is not the solution yet. There is an open issue related to this pm2 option here: https://github.com/Unitech/pm2/issues/5208. From the looks of it I don't expect it to be resolved anytime soon. So the above option should work but I don't think it does at the moment with the current version of pm2 as of this writing (5.1.12)

Upvotes: 4

Tarun Lalwani
Tarun Lalwani

Reputation: 146500

I have looked at the code of pm2

https://github.com/Unitech/pm2/blob/6090b0971abca6fcb2d796e560f2a72b81ab5707/lib/God.js

And it doesn't seems to have any logic in terms of not starting a process on a successful exit. The feature you are asking for doesn't exists. It is same for cluster as well as fork mode.

You can test that using test.js

setTimeout(()=>process.exit(), 2000);

Fork mode

$ pm2 start test.js && sleep 5
[PM2] Starting /Users/tarunlalwani/Documents/Projects/SO/pm2exit/test.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬─────┬──────────┬──────────────┬──────────┐
│ App name │ id │ version │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem      │ user         │ watching │
├──────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼─────┼──────────┼──────────────┼──────────┤
│ test     │ 0  │ N/A     │ fork │ 5889 │ online │ 0       │ 0s     │ 0%  │ 9.4 MB   │ tarunlalwani │ disabled │
└──────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴─────┴──────────┴──────────────┴──────────┘
 Use `pm2 show <id|name>` to get more details about an app
$ pm2 logs
PM2        | 2019-08-18T11:40:23: PM2 log: App [test:0] exited with code [0] via signal [SIGINT]
PM2        | 2019-08-18T11:40:23: PM2 log: App [test:0] starting in -fork mode-
PM2        | 2019-08-18T11:40:23: PM2 log: App [test:0] online
PM2        | 2019-08-18T11:40:25: PM2 log: App [test:0] exited with code [0] via signal [SIGINT]
PM2        | 2019-08-18T11:40:25: PM2 log: App [test:0] starting in -fork mode-
PM2        | 2019-08-18T11:40:25: PM2 log: App [test:0] online

$ pm2 delete test
$ pm2 start test.js -i 2&& sleep 5
[PM2] Starting /Users/tarunlalwani/Documents/Projects/SO/pm2exit/test.js in cluster_mode (2 instances)
[PM2] Done.
┌──────────┬────┬─────────┬─────────┬──────┬────────┬─────────┬────────┬─────┬───────────┬──────────────┬──────────┐
│ App name │ id │ version │ mode    │ pid  │ status │ restart │ uptime │ cpu │ mem       │ user         │ watching │
├──────────┼────┼─────────┼─────────┼──────┼────────┼─────────┼────────┼─────┼───────────┼──────────────┼──────────┤
│ test     │ 0  │ N/A     │ cluster │ 5993 │ online │ 0       │ 0s     │ 0%  │ 27.6 MB   │ tarunlalwani │ disabled │
│ test     │ 1  │ N/A     │ cluster │ 5994 │ online │ 0       │ 0s     │ 0%  │ 20.8 MB   │ tarunlalwani │ disabled │
└──────────┴────┴─────────┴─────────┴──────┴────────┴─────────┴────────┴─────┴───────────┴──────────────┴──────────┘
 Use `pm2 show <id|name>` to get more details about an app

$ pm2 logs
PM2      | App name:test id:0 disconnected
PM2      | App [test:0] exited with code [0] via signal [SIGINT]
PM2      | App [test:0] starting in -cluster mode-
PM2      | App name:test id:1 disconnected
PM2      | App [test:1] exited with code [0] via signal [SIGINT]
PM2      | App [test:1] starting in -cluster mode-
PM2      | App [test:0] online
PM2      | App [test:1] online
PM2      | App name:test id:0 disconnected
PM2      | App [test:0] exited with code [0] via signal [SIGINT]
PM2      | App [test:0] starting in -cluster mode-
PM2      | App name:test id:1 disconnected
PM2      | App [test:1] exited with code [0] via signal [SIGINT]
PM2      | App [test:1] starting in -cluster mode-
PM2      | App [test:0] online
PM2      | App [test:1] online
PM2      | App name:test id:0 disconnected

$ pm2 delete test

Alternative

As an alternative you can use Supervisord

You can use the exitcodes in the configuration file

http://supervisord.org/configuration.html

The list of “expected” exit codes for this program used with autorestart. If the autorestart parameter is set to unexpected, and the process exits in any other way than as a result of a supervisor stop request, supervisord will restart the process if it exits with an exit code that is not defined in this list.

Upvotes: 6

mwieczorek
mwieczorek

Reputation: 2252

Add the --no-autorestart option to pm2 start, or in your JSON configuration file.

Upvotes: -3

Related Questions