How to pass execution arguments to app using PM2?

node.jsExpressForeverPm2

node.js Problem Overview


I am using pm2 to start my app but I'm not able to pass argument to it. The command I am using is pm2 start app.js -- dev. Though this works with forever.

node.js Solutions


Solution 1 - node.js

If you want to pass node arguments from CLI then

pm2 start myServer.js --node-args="--production --port=1337"

.

Edited

you can add any arguments after --

pm2 start app.js -- --prod --second-arg --third-arg

Sails docs for deploymemt.

Solution 2 - node.js

You can do as stated in this ticket: https://github.com/Unitech/pm2/issues/13

Though if you're passing the environment you may want to consider leveraging environment variables. With this you create a variable which can be accessed by any process in that environment with process.env.*.

So you have a configuration file config.json:

{
   "dev": {
	   	"db": {
	   		"hosts":["localhost"],
	   		"database": "api"
	   	},
	   	"redis": {
	   		"hosts": ["localhost"]
	   	}
   },
   "staging": {
		"db": {
	   		"hosts":["1.1.1.1"],
	   		"database": "api"
	   	},
	   	"redis": {
	   		"hosts": ["2.2.2.2"]
	   	}
   },
   "production": {
   		"db": {
	   		"hosts":["1.1.1.1", "1.1.1.2", "1.1.1.3"],
	   		"database": "api"
	   	},
	   	"redis": {
	   		"hosts": ["2.2.2.2", "2.2.2.3"]
	   	}
   }
}

Then you import your config:

var config=require('./config.json')[process.env.NODE_ENV || 'dev'];

db.connect(config.db.hosts, config.db.database);

Then you'd set the variable in your environment via shell:

export NODE_ENV=staging
pm2 start app.js

The environment variable will last as long as your session. So you'll have to set it in the ~/.bashrc file for that user for the variable to persist. This will set the variable every session.

PM2 has a deploy system which allows you to set an environment variable each time before your app is daemonized. This is how daemons in POSIX systems typically take parameters, because those parameters aren't lost with the process. Given with your circumstance it might not matter so much, but its a good practice.

Moreover you should consider stop/starting locally, and restarting(if in cluster mode) whenever possible to prevent downtime when in production.

Solution 3 - node.js

It is possible to define arguments with the process.

You can define a new process in ecosystem.config.js with an args key, like so:

{
  name            : 'my-service',
  script          : './src/service.js',
  args            : 'firstArg secondArg',
},
{
  name            : 'my-service-alternate',
  script          : './src/service.js',
  args            : 'altFirstArg altSecondArg',
}

Here, the two processes use the same file (service.js), but pass different arguments to it.

Note that these arguments are handled within service.js. In my case I just used process.argv[2] to get the first argument, and so on.

Solution 4 - node.js

You can send arguments to your script by passing them after --. For example: pm2 start app.js -i max -- -a 23 // Pass arguments after -- to app.js

Solution 5 - node.js

I have tested and it works in my windows machine. Below is the complete solution to pass arguments to nodejs app using pm2.

** There are also 2 types of argument

  1. node-args - to use before npm start
  2. args - to use in your node program

There are 2 ways to pass arguments with pm2.

Option 1: pass by argument with pm2 commands.

Option 2: by using config file e.g ecosystem.config.js

Option 1 (Pass arg by commands):

pm2 start app/myapp1.js --node-args="--max-http-header-size=80000" -- arg1 arg2
//Access the arg as below in your node program.
console.log(process.argv[2]); // arg1
console.log(process.argv[3]); // arg2

Option 2 (Using config file): If you are using ecosystem.config.js. you can define with the following configuration:

    {
      name: 'my-app',
      script: 'app\\myapp1.js',
      env: {
        NODE_ENV: 'DEV',
        PORT : 5051
      },
      node_args: '--max-http-header-size=80000',
      args : 'arg1 arg2',
      instances: 1,
      exec_mode: 'fork'
    }

To start as dev mode:

pm2 start --name myapp  app/myapp1.js -- .\ecosystem.config.js

To start as production mode, just add --env=production

pm2 start --name myapp  app/myapp1.js -- .\ecosystem.config.js --env=production 
//Access the arg as below in your node program.
console.log(process.argv[2]); // arg1
console.log(process.argv[3]); // arg2

Solution 6 - node.js

I always use PM2 to run my python scripts in Linux environment. So consider a script has a single parameter and needs to run continously after some amount if time, then we can pass it like this:

pm2 start <filename.py> --name <nameForJob> --interpreter <InterpreterName> --restart-delay <timeinMilliseconds> -- <param1> <param2>

filename.py is Name of the python script, without <> symbols, I want to run using PM2
nameForJob is the Meaningful name for the job, without <> symbols
InterpreterName is the python interpreter for running script, usually it is python3 in linux
timeinMilliseconds is the time our script needs to wait and re-run again
param1 is the first parameter for the script
param2 is the second parameter for the script.

Solution 7 - node.js

Well there are 2 ways you can do to pass the parameters from pm2 to nodejs in CLI:

  • pm2 start app.js -- dev --port=1234 (note there is an extra space between -- and dev)
  • pm2 start app.js --node-args="dev --port=1234"

Both ways, you will find these values exist in process.argv (['dev','--port=1234'])

Solution 8 - node.js

You can pass args for node just like that:

NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_ENV=dev pm2 start server.js --name web-server

Solution 9 - node.js

I'll complement the answers above for npm scripts

For npm scripts
// package.json
{
  "scripts": {
    "start": "pm2 start --node-args=\"-r dotenv/config\" index.js"
  }
}

npm run start runs pm2 start for index.js with node-args -r dotenv/config which include environment variables from .env file with dotenv

Solution 10 - node.js

From the pm2 docs

//Inject what is declared in env_production
$ pm2 start app.js --env production 

//Inject what is declared in env_staging
$ pm2 restart app.js --env staging

Solution 11 - node.js

You need to start pm2 with something like: pm2 start app.js --name "app_name" -- arg1 arg2

Then in your code, you can get your args with: console.log(process.argv);

process.argv is a list like this: [ '/usr/local/bin/node', '/usr/local/lib/node_modules/pm2/lib/ProcessContainerFork.js', 'arg1', 'arg2' ]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3373581View Question on Stackoverflow
Solution 1 - node.jsNishchitView Answer on Stackoverflow
Solution 2 - node.jststurzlView Answer on Stackoverflow
Solution 3 - node.jsTravisView Answer on Stackoverflow
Solution 4 - node.jsAlexView Answer on Stackoverflow
Solution 5 - node.jsjunnyeaView Answer on Stackoverflow
Solution 6 - node.jsPrasad NadigerView Answer on Stackoverflow
Solution 7 - node.jsXinView Answer on Stackoverflow
Solution 8 - node.jsonsmakView Answer on Stackoverflow
Solution 9 - node.jsSvyatView Answer on Stackoverflow
Solution 10 - node.jskennyView Answer on Stackoverflow
Solution 11 - node.jsDaian GanView Answer on Stackoverflow