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

4

12

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.

Serpentiform answered 25/4, 2017 at 14:48 Comment(1)
Are you sure? Because for me both work the same way. setTimeout(()=>process.exit(), 2000); and be it cluster mode or fork mode both restartWilderness
T
4

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)

Tabbatha answered 7/1, 2022 at 2:20 Comment(1)
Although late, it's still the correct answer now :) AwesomeSerpentiform
W
6

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.

Wilderness answered 18/8, 2019 at 6:12 Comment(2)
Not the answer I wanted to hear, but an authoritative one. I personally worked around the limitation by invoking PM2 API from my Node application to call for a stop instead of just exiting, but it's a poor workaround for many reasons. Any other similar tools that can support exit code logic?Sheffield
@Xan, I updated the answer with the description of alternative as suchWilderness
T
4

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)

Tabbatha answered 7/1, 2022 at 2:20 Comment(1)
Although late, it's still the correct answer now :) AwesomeSerpentiform
H
1

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]
}]
Highstepper answered 19/3, 2024 at 0:21 Comment(0)
H
-3

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

Hogweed answered 18/6, 2018 at 16:34 Comment(2)
This prevents pm2 from restarting even in case of error (i.e.: code != 0)Serpentiform
This is important and nice if you have any other monitoring tool that takes care of the restarting. Good for docker orchestration. Nice to know and have in that case.Blanchblancha

© 2022 - 2025 — McMap. All rights reserved.