pm2 --update-env option seems not working - node.js

I launched my node app by using ecosystem.config.js like this.
pm2 start ecosystem.config.js
And my ecosystem.config.js is here.
module.exports = {
/**
* Application configuration section
* http://pm2.keymetrics.io/docs/usage/application-declaration/
*/
apps : [
// First application
{
name : "API",
script : "./app/index.js",
env: {
COMMON_VARIABLE: "true"
},
env_production : {
NODE_ENV: "production"
}
},
],
/**
* Deployment section
* http://pm2.keymetrics.io/docs/usage/deployment/
*/
deploy : {
production : {
user : "node",
host : "212.83.163.1",
ref : "origin/master",
repo : "git#github.com:repo.git",
path : "/var/www/production",
"post-deploy" : "npm install && pm2 startOrRestart ecosystem.json --env production"
},
dev : {
user : "node",
host : "212.83.163.1",
ref : "origin/master",
repo : "git#github.com:repo.git",
path : "/var/www/development",
"post-deploy" : "npm install && pm2 startOrRestart ecosystem.json --env dev",
env : {
NODE_ENV: "dev"
}
}
}
}
Then I tried to change the config file for watching mode on. I read this document so, I added watch: true attribute, then I tried pm2 restart ecosystem.config.js --update-env for applying changed config.
The app is restarted and attribute seems to be changed, because when I try pm2 list the watching is enabled. But my app is not restarted after change my code.
So, I just tried pm2 delete 0, pm2 start ecosystem.config.js then It's working well.
Why does --update-env options not working? What do I do wrong?

The only reliable ways I've found to update a pm2 app config is either pm2 kill to stop the daemon, or pm2 delete <id|name> && pm2 start ecosystem.config.js for an individual app (as #hshan mentioned).
This issue claims it was fixed in 2014, but the comments there, plus the string of other questions/issues I found would seem to indicate otherwise:
https://github.com/Unitech/pm2/issues/528
Update: Ongoing discussion here as well: https://github.com/Unitech/pm2/issues/3192

pm2 restart <pid> --update-env worked for me as suggested in this answer

pm2 restart ecosystem.config.js --env production
I don't need --update-env but I do need to specify the env again on restart
Another option that I found was specifying the var on the cmd line:
MY_VAR=1234 pm2 restart ecosystem.config.js
Interestingly, this keeps it in the previous env, but the cmd line var will overwrite the values you have in your ecosystem.config.js for the same var.
However
MY_VAR=1234 pm2 restart ecosystem.config.js --env production
WILL overwrite the cmd line MY_VAR if you have one defined in your ecosystem for production.

This update error happend when it tried to write to Z:\ drive
However, there is no Z:\ drive in my Windows OS machine
Below helped fix the issue:
1 . Add user environment variable as below:
PM2_HOME=%USERPROFILE%\.pm2
2 . Then kill pm2 daemon once
pm2 kill
Now pm2 update works fine.

Related

How to use pm2 start npm in a specific directory?

Is there a CLI tag for running pm2 start npm -- start in a specific directory? I looked around but could not find an answer.
On the other hand, when I run pm2 without npm, I can specify which directory I want to run pm2 in. For example:
pm2 start /opt/www/myapp/index.js
Is there any way to add a path tag to the pm2 start npm -- start command?
You can use something like this:
cd /directory/of/my/app ; pm2 start npm -- start
You can also write an ecosystem file to parameter you app:
{
"apps": [
{
"name": "my-app",
"cwd": "/path/to/app",
"script": "npm",
"args": "start"
}
]
}
To generate an empty ecosystem file:
pm2 init simple
this will generate a file named ecosystem.config.js that you can rename.
Then to start application:
pm2 start ecosystem.config.js
ecosystem doc: https://pm2.keymetrics.io/docs/usage/application-declaration/

How to pass NODE_ENV=production to pm2?

I have this node app deployed and runs fine with NODE_ENV=production yarn start.
I can demonize the app using
pm2 start npm -- start
but then it defaults to NODE_ENV=development config.
And when I use
pm2 start npm -- start NODE_ENV=production
It still starts with development config.
Also I tried passing the env using a process.yml file
apps:
- script : index.js
watch: true
instances: 4
env :
NODE_ENV: production
but pm2 start npm -- start process.yml still loads the development configs.
How can I fix this?
The reason you might be facing this is because you would have started pm2 with development once. Now it will use that env until you kill it. Following these steps should help
./node_modules/.bin/pm2 kill
NODE_ENV=production ./node_modules/.bin/pm2 start server.js
You can also use --update-env. From the official docs
By default we want that PM2 doesn’t change process environment while
restarting or reloading so they are immutable. If you want to update
them, you must use --update-env :
try this:
export NODE_ENV=production&&pm2 start server.js
export NODE_ENV=production && pm2 start ecosystem.config.js
Following line helped me! Thanks to #mehdi parastar and #abhinavd
Try this, if you are using a pm2, the below code works for me
sudo NODE_ENV=production pm2 start app.js
You can solve it using this command (with double quotes):
sudo pm2 start "NODE_ENV=production yarn start"
You just do it like this ->
NODE_ENV=production pm2 restart <id|name> --update-env
You can check the docs here:
PM2 - Update Env Variables docs

how to pass custom arguments to app

I'm trying to run node app with pm2 via command line and pass only one argument with it
pm2 start app.js --node-args="41"
pm2 start app.js --env dev --node-args="41"
I tried to run it with developement environment and without it but in both ways it didn't worked.
What is the way to do it?
The pm2 command line option --node-args is for passing arguments to the Node.js V8 engine, not to the program running on that engine.
The correct way to pass arguments to your program is this:
pm2 start app.js -- 41
For dev environment:
pm2 start app.js --env dev -- 41
So basically, anything you add after the last two dashes is accessible through process.argv as an array.
You can define a process file at your project root and pass your env and args like this:
process.json
{
"apps" : [
{
"name" : "app-prod",
"script" : "app.js",
"env": {
"NODE_ENV": "production"
}
},
{
"name" : "app-dev",
"script" : "app.js",
"args" : "41",
"env": {
"NODE_ENV": "development"
}
}
]
}
This definition will allow you to pass command line argument (41) that will only be available in your development version.
Then, if you want to run development version of your app, execute it as follows
pm2 start process.json --only app-dev

How to start pm2 process with DEBUG option

I have an express app that I start in terminal with following command to enable debug logs in it:
DEBUG=custom:* npm start (on Ubuntu)
SET DEBUG=custom:* & npm start (on Windows)
On production server, I start app with PM2 using following command:
pm2 start bin/www -i 0
But this does not enable the debug logs in my code, so the debug statements are not added to the logs, only console.error() are added to the log files. How can I pass the DEBUG=custom:* option while starting my app with PM2?
Try DEBUG='custom:*' pm2 start bin/www -i 0
If you are restarting an existing process add the --update-env flag:
DEBUG='custom:*' pm2 restart bin/www -i 0 --update-env
Mikko was correct but if you add that to package.json scripts, it won't work!
"scripts": {
"start": "DEBUG='custom:*' pm2 start bin/www -i 0",
...
},
Because DEBUG='custom:*' is given to pm2 process NOT your process. So in this case you have to use an ecosystem file and add DEBUG setting in ecosystem file, e.g.
"scripts": {
"start": "pm2 start ecosystem.config.js",
...
},
//in ecosystem.config.js add this
env: {
NODE_ENV: 'development',
DEBUG: 'custom:*'
},

Can pm2 run an 'npm start' script

Is there a way for pm2 to run an npm start script or do you just have to run pm2 start app.js
So in development
npm start
Then in production with pm2 you would run something like
pm2 start 'npm start'
There is an equivalent way to do this in forever:
forever start -c "npm start" ./
PM2 now supports npm start:
pm2 start npm -- start
To assign a name to the PM2 process, use the --name option:
pm2 start npm --name "app name" -- start
Those who are using a configuration script like a .json file to run the pm2 process can use npm start or any other script like this -
my-app-pm2.json
{
"apps": [
{
"name": "my-app",
"script": "npm",
"args" : "start"
}
]
}
Then simply -
pm2 start my-app-pm2.json
Edit - To handle the use case when you have this configuration script in a parent directory and want to launch an app in the sub-directory then use the cwd attribute.
Assuming our app is in the sub-directory nested-app relative to this configuration file then -
{
"apps": [
{
"name": "my-nested-app",
"cwd": "./nested-app",
"script": "npm",
"args": "start"
}
]
}
More detail here.
To use npm run
pm2 start npm --name "{app_name}" -- run {script_name}
I needed to run a specific npm script on my app in pm2 (for each env)
In my case, it was when I created a staging/test service
The command that worked for me (the args must be forwarded that way):
pm2 start npm --name "my-app-name" -- run "npm:script"
examples:
pm2 start npm --name "myApp" -- run "start:test"
pm2 start npm --name "myApp" -- run "start:staging"
pm2 start npm --name "myApp" -- run "start:production"
Hope it helped
Yes. Use pm2 start npm --no-automation --name {app name} -- run {script name}. It works. The --no-automation flag is there because without it PM2 will not restart your app when it crashes.
you need to provide app name here like myapp
pm2 start npm --name {appName} -- run {script name}
you can check it by
pm2 list
you can also add time
pm2 restart "id" --log-date-format 'DD-MM HH:mm:ss.SSS'
or
pm2 restart "id" --time
you can check logs by
pm2 log "id"
or
pm2 log "appName"
to get logs for all app
pm2 logs
I wrote shell script below (named start.sh).
Because my package.json has prestart option.
So I want to run npm start.
#!/bin/bash
cd /path/to/project
npm start
Then, start start.sh by pm2.
pm2 start start.sh --name appNameYouLike
Yes we can, now pm2 support npm start, --name to species app name.
pm2 start npm --name "app" -- start
See to enable clustering:
pm2 start npm --name "AppName" -i 0 -- run start
What do you think?
If you use PM2 via node modules instead of globally, you'll need to set interpreter: 'none' in order for the above solutions to work. Related docs here.
In ecosystem.config.js:
apps: [
{
name: 'myApp',
script: 'yarn',
args: 'start',
interpreter: 'none',
},
],
pm2 start npm --name "custom_pm2_name" -- run prod
"scripts": {
"prod": "nodemon --exec babel-node ./src/index.js"
}
This worked for me when the others didnt
You can change directory to your project
cd /my-project
then run
pm2 start "npm run start" \\ run npm script from your package.json
read more here
For the normal user
PM2 now supports npm start:
pm2 start npm -- start
To assign a name to the PM2 process, use the "--name" option:
pm2 start npm --name "your desired app name" -- start
For the root user
sudo pm2 start npm -- start
To assign a name to the PM2 process, use the "--name" option:
sudo pm2 start npm --name "your desired app name" -- start
Yes, Absolutely you can do it very efficiently by using a pm2 config (json) file with elegance.
package.json file (containing below example scripts)
"scripts": {
"start": "concurrently npm:server npm:dev",
"dev": "react-scripts start",
"build": "node ./scripts/build.js",
"eject": "react-scripts eject",
"lint": "eslint src server",
"shivkumarscript": "ts-node -T -P server/tsconfig.json server/index.ts"
}
Suppose we want to run the script named as 'shivkumarscript' with pm2 utility. So, our pm2 config file should be like below, containing 'script' key with value as 'npm' and 'args' key with value as 'run '. Script name is 'shivkumarscript' in our case.
ecosystem.config.json file
module.exports = {
apps: [
{
name: "NodeServer",
script: "npm",
automation: false,
args: "run shivkumarscript",
env: {
NODE_ENV: "development"
},
env_production: {
NODE_ENV: "production"
}
}
]
}
Assuming that you have already installed Node.js, NPM and PM2 on your machine. Then below should be the command to start the application through pm2 which will in turn run the npm script (command line mentioned in your application's package.json file):
For production environment:
pm2 start ecosystem.config.js --env production --only NodeServer
For development environment:
pm2 start ecosystem.config.js --only NodeServer
...And Boooom! guys
It's working fine on CentOS 7
PM2 version 4.2.1
let's take two scenarios:
1. npm start //server.js
pm2 start "npm -- start" --name myMainFile
2. npm run main //main.js
pm2 start "npm -- run main" --name myMainFile
Unfortunately, it seems that pm2 doesn't support the exact functionality you requested https://github.com/Unitech/PM2/issues/1317.
The alternative proposed is to use a ecosystem.json file Getting started with deployment which could include setups for production and dev environments. However, this is still using npm start to bootstrap your app.
pm2 start ./bin/www
can running
if you wanna multiple server deploy
you can do that. instead of pm2 start npm -- start
Don't forget the space before start
pm2 start npm --[space]start
so the correct command is:
pm2 start npm -- start
To run PM2 with npm start method and to give it a name, run this,
pm2 start npm --name "your_app_name" -- start
To run it by passing date-format for logs,
pm2 start npm --name "your_name" --log-date-format 'DD-MM HH:mm:ss.SSS' -- start
Now, You can use after:
pm2 start npm -- start
Follow by https://github.com/Unitech/pm2/issues/1317#issuecomment-220955319
for this first, you need to create a file run.js and paste the below code on that.
const { spawn } = require('child_process');
//here npm.cmd for windows.for others only use npm
const workerProcess = spawn('npm.cmd', ['start']);
workerProcess.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
workerProcess.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
workerProcess.on('close', function (code) {
console.log('child process exited with code ' + code);
});
and run this file with pm2.
pm2 start run.js
List item

Resources