How do I limit the number of auto-restarts on pm2? - node.js

I have a node server running on pm2 which depends on some external services.
When those servers go down I pm2 starts restarting my app, but this will keep going until it clogs up my cpu and ram on the server, restarting as much as 50 times a minute.
Is there a way to limit the numbers of restarts on pm2? There is a way to restart the server when the server reaches a certain RAM memory level, so I would hope this feature I am asking for exists.

You can use combination of max_restarts and min_uptime to restrict the app to restart consecutively.
number of consecutive unstable restarts (less than 1sec interval or custom time via min_uptime) before your app is considered errored and stop being restarted
More information about max_restarts and min_uptime is available here

Use PM2 ecosystem.config.js file like this:
module.exports = {
apps : [{
name: "app",
script: "./app.js",
merge_logs: true,
max_restarts": 50, //Here you can define your max restarts
instances: "max",
max_memory_restart: "200M",
env: {
NODE_ENV: "development",
},
env_production: {
NODE_ENV: "production",
}
}]
}
Start your server by following command:
pm2 start ecosystem.config.js //uses variables from `env`
pm2 start ecosystem.config.js --env production //uses variables from `env_production`
For more details see below link:
PM2 Runtime | Guide | Ecosystem File

Options for config file if you have: ecosystem.config.js
{
watch_delay: 5000,
exp_backoff_restart_delay: 100,
restart_delay: 1000,
max_restarts: 2,
min_uptime: 5000,
autorestart: false,
}
Otherwise, give the same command line, as below:
pm2 start app.js --restart-delay=3000
pm2 start app.js --no-autorestart
They themselves know the issue, so see the 1st link below:
https://pm2.keymetrics.io/docs/usage/restart-strategies/
https://pm2.keymetrics.io/docs/usage/process-management/
Mine got fixed only after watch_delay: 5000, and nothing else was required.

Related

How do you configure pm2 ignore_watch for multiple directories?

I am running PM2 on windows 10 and have the following as my ecosystem.config.json file use to start the process.
module.exports = {
apps : [{
name : "myApp",
script : "./server.js",
watch : true,
watch_delay: 5000,
ignore_watch: ['node_modules', 'tracking'],
env: {
"NODE_ENV": "production",
}
}]
}
Whenever I update something in the tracking directory is causes a restart. If I move the file location to node_modules and remove tracking from the ignore_watch then it works. I have tried several other paths but anything other than node_modules does NOT seem to work with PM2.
Is the formatting incorrect or am I just missing something or is there a known issue in windows?
PM2 watch and unwatch folder and transpile with babel-node
I was looking for a simple solution for the development server!
Problem: When uploading files to the development server 'express-fileupload' PM2 detects a change in the folders and restarts the process.
I clarify this operation is fine because we had PM2 configured to monitor the entire project!
"ecosystem.config.js" is the configuration; it is simple. You can expand it with the official documentation of PM2. I leave it at the end! How do we fix it, to prevent restarting the process each time we upload a file?
Create the configuration file in the root folder:
ecosystem.config.js
module.exports = {
apps: [
{
name: "DEH",
script: "./server/index.js",
interpreter: "./node_modules/#babel/node/bin/babel-node.js",
interpreter_args: "./node_modules/#babel/node/bin/babel-node",
watch: ["server"],
watch_delay: 1000,
ignore_watch: [
"node_modules",
"./server/src/files",
"./server/src/pdf",
],
watch_options: {
followSymlinks: false,
},
},
],
};
To run it:
pm2 start ecosystem.config.js
Note that ignore_watch has an array with elements that will not be checked.
The interpreter points to the folder where it was installed locally: if you don't specify it you will have to install babel-node globally (I don't recommend it)

How to add node run option --max-http-header-size and add name to pm2 start command

How would I start a pm2 process with the —max-http-header-size node option, as well as name the process.
I have a server with multiple micro-services, one of the services is a web scraper.
This web scraper accepts requests with headers over the nodejs default 8kb limit. So, to run my app locally have to add the --max-http-header-size node option.
I've cloned my app to the server, but don't know how to set --max-http-header-size, nor do I know how to name the process within the pm2 start command.
So far my attempts have looked like this.
// this sets the name, but I don't know how to add the option `--max-http-header-size`
pm2 start npm --name "{REPONAME}" -- start
pm2 start node --name "scraper" --max-http-header-size 15000 app.js
pm2 start node --max-http-header-size 15000 app.js -- --name "scraper"
The accepted answer by David Harvey did not work for me as of Node 16. Instead, I had to use node_args, something like this:
{
"apps" : [{
"name" : "myapp",
"script" : "./app.js",
"node_args": "--max-http-header-size=256000",
"env": {
"NODE_ENV": "production",
}
}]
}
What you're looking for is called environment variables! You can pass environment variables to pm2 using a file that loads your server like this:
module.exports = {
apps : [
{
name: "myapp",
script: "./app.js",
watch: true,
node_args: "--max-http-header-size=16000"
}
]
}
Here's more about it too:
https://pm2.keymetrics.io/docs/usage/environment/

Problem running express app with pm2 using ecosystem config file

When I run my Node.js express app using node command everything works fine!
When using pm2 server./bin/www` my pm2 status is something like this:
And my app works in this situation. Also when I use pm2 start bin "./bin/www" -i 0 my pm2 list shows:
And yet again my app works. But using following config file:
module.exports = {
apps: [{
name: 'cdn',
script: './bin/www',
instances: 0,
exec_mode: 'cluster',
watch: true,
env: {
NODE_ENV: 'production',
PORT: process.env.PORT || '5555',
}
}]
};
the application while listening on the specified port does not work and prints no error messages and my pm2 status is:
How should I use config file correctly?
Maybe you forgot .config.js in your ecosystem filename.
I lost hours of my day looking for the exact same problem yours and a ignored line of pm2 docs alerts me what I forgot (a weird requirement).
Note that using a Javascript configuration file requires to end the file name with .config.js

How to get pm2 process to watch after it has been stopped/ restarted?

My pm2 process starts using their default ecosystem file structure:
ecosystem.config.js
module.exports = {
apps: [{
env: {
NODE_ENV: "development"
},
error_file: "./logs/error.log",
ignore_watch: ["logs", "node_modules"],
log_date_format: "YYYY-MM-DD HH:mm:ss Z",
name: "my-app",
out_file: "./logs/output.log",
script: "./server.js",
watch: true
}]
}
I start the process with pm2 start ecosystem.config.js and that works fine, with the app reloading on file changes.
But when I stop the process with pm2 stop ecosystem.config.js, and then start it again with pm2 start ecosystem.config.js, pm2 does not watch for files, despite the display column of watching being enabled.
The only way to start the process up again and have the watch work is to delete the pm2 process, and then start up a new one again.
Am I missing something to make a stop or restart work with watch?
Thanks.
The pm2 watch & restart documentation had the answer (must have glossed over it on first read):
Restart with --watch will toggle the watch parameter.
Looks like omitting that --watch flag on already-existing pm2 instances will not toggle the watch parameter in the ecosystem.config.js file. The watch parameter is only toggled on initial process execution, not subsequent ones.
So stopping the process, then starting again with pm2 start ecosystem.config.js --watch does the trick!
Try adding
watch_options: {
"usePolling": true
}
See here: http://pm2.keymetrics.io/docs/usage/watch-and-restart/
This is not a PM2 specific option, but rather a chokidar option which is used by PM2.
The documentation of those options can be found here.
https://stackoverflow.com/users/7575111/nulldev
watch_options: {
"usePolling": true
}
The answer was helpful to me as a trial environment that doesn't cost me restarting the app every time

How to specify a port number for pm2

I'm trying to use pm2 to manage a node.js cluster
pm2 start . -i 3
I'm currently running the app on heroku and using a Procfile with the above command, but I cannot figure out how to configure pm2 to use the existing PORT env var. Something like pm2 start . -p $PORT
What am I missing?
You can use an environment variable.
For example:
NODE_PORT=3002 pm2 start -i 0 app.js
Here is how to read the value in app:
console.log(process.env.NODE_PORT);
Or, if you are building an Express app:
PORT=3002 pm2 start -i 0 ./bin/www
Express loads PORT automatically when the application starts.
You need to use -- to tell pm2 to stop parsing his options and give the rest to the program, then when you spawn direct binary, you need to tell pm2 that you don't want to use nodejs, so :
pm2 start rethinkdb --interpreter none -- --port 8082
You see you need -- --port 8082
An easy way of telling your server application on which port to run is through PM2's
ecosystem configuration files
in conjunction with properly configured use of $PORT environment vars inside your server application. That means your server reads $PORT environment var to start the server or microservice on specified port.
There are different formats available you can choose for the file to have. I personally use the CommonJS module format (amongst other options are JSON and YAML).
Inside ecosystem.config.js you specify one entry object for each server instance you want to launch through PM2.
The point is that you can also specify environment vars for the different processes and that way you can setup $PORT for all the processes. The following is an example config for three different processes.
module.exports = {
apps : [
{
name : "Main API server",
script : "./backend/dist/main.js",
instances : "2",
exec_mode : "cluster",
env: {
NODE_ENV: "production",
PORT: 4300
}
},
{
name : "Worker server 1",
script : "./backend-worker/dist/main.js",
instances : "1",
exec_mode : "fork",
env: {
NODE_ENV: "production",
PORT: 4000,
},
},
{
name : "Worker server 2",
script : "./backend-worker/dist/main.js",
instances : "1",
exec_mode : "fork",
env: {
NODE_ENV: "production",
PORT: 4001,
}
},
]
}
One note: This configuration uses PM2 as a loadbalancer for the first process that runs as cluster on two cores. The other (worker-)processes are run each on is on process on the specified port.
An example snippet of server startup code using the environment $PORT var for a NodeJS server is following:
// ...
const port = (process.env.PORT) ? process.env.PORT : 4300
console.log('$PORT: ', port)
const server = await app.listen(port, '0.0.0.0')
// ...
When you have all in place you simply call following to startup your servers:
pm2 start ecosystem.config.js

Resources