Why is PM2 watching but not catching changes to code? - node.js

I read related posts on this question, but they don't help.
I'm running a Node-Express app in a windows environment using PM2 with pm2-windows-service. Until today it's been running node just fine and reloading Node when I save changes to my code. Today it stopped working. When I make changes, Node still serves up the old code. Even when I manually restart PM2. Plus, when I manually start PM2 it rapidly restarts Node until I kill Node with Task Manager.
Furthermore, even when I kill PM2, delete the PM2 app, and try manually running Node or nodemon, I still get the old code.
Baffling. Any theories?
Thank you!
Here's my ecosystem.config.js file:
module.exports = {
apps : [{
name: 'sm_api',
script: 'server/index.js',
log_date_format : "YYYY-MM-DD HH:mm Z",
// Options reference: https://pm2.io/doc/en/runtime/reference/ecosystem-file/
args: 'one two',
instances: 'max',
error_file : "C:\\pm2_system\\.pm2\\logs\\sm-api-error",
out_file: "C:\\pm2_system\\.pm2\\logs\\sm-api-out",
autorestart: true,
watch: true,
max_restarts: 10,
max_memory_restart: '1G',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
},
exec_mode: 'cluster'
}],
};

Related

Activating cron restarts on pm2 after reboot

Currently, I have this ecosystem.config.js file setup:
module.exports = {
apps: [
{
name: 'Bot',
script: `./src/index.js`,
watch: false,
autorestart: true,
},
{
name: 'Post Stats',
script: `./jobs/postStats.js`,
cron_restart: '*/30 * * * *',
watch: false,
autorestart: false,
},
],
}
I then run this with pm2 start ecosystem.config.js and everything works fine, with the various files restarting when expected.
To get the process to start automatically on system start up, I run pm2 startup and run the command suggested (as shown in https://pm2.keymetrics.io/docs/usage/startup/). I then run pm2 save to save the current config.
Then, when I restart the server, and the Bot process starts as expected but the Post Stats process doesn't.
How can I have the cron restart re-registered when the server restarts?

Node/Express server deploy with Heroku and PM2

Attempting to add clustering ability via PM2 and deploy via my Node/Express application.
I've set up the following command:
pm2 start build/server/app.js -i max
The above works fine locally. I'm testing the functionality on a staging environment on Heroku via Performance 1X.
The above shows the log for the command but attempting 1 instance rather than max. It shows typical info after successfully running pm2 start however you can see app immediately crashes afterward.
Any advice or guidance is appreciated.
I ended up using the following documentation: https://pm2.keymetrics.io/docs/integrations/heroku/
Using a ecosystem.config.js with the following:
module.exports = {
apps : [
{
name: `app-name`,
script: 'build/server/app.js',
instances: "max",
exec_mode: "cluster",
env: {
NODE_ENV: "localhost"
},
env_development: {
NODE_ENV: process.env.NODE_ENV
},
env_staging: {
NODE_ENV: process.env.NODE_ENV
},
env_production: {
NODE_ENV: process.env.NODE_ENV
}
}
],
};
Then the following package.json script handles the deployment per the environment I am looking to deploy e.g. production:
"deploy:cluster:prod": "pm2-runtime start ecosystem.config.js --env production --deep-monitoring",
I got the same error but I fixed it by adding
{
"preinstall":"npm I -g pm2",
"start":"pm2-runtime start build/server/app.js -i 1"
}
To my package.json file
This is advised for production environment
But running
pm2 start build/server/app.js -i max
Is for development purpose

How to configure PM2 to start certain applications based on the system's environment variables?

I went through the PM2 documentation and it looks like it provides the facility to send environment variables to your application but I could not find any information on how to configure PM2 such that it starts applications based on the system's environment variables.
For example, I have the following config file -
module.exports = {
apps: [{
name: 'app',
script: 'app.js',
instances: 1,
autorestart: true,
watch: true
}, {
name: 'worker',
script: './server/sync.js',
instances: 1,
autorestart: true,
watch: true
}]
};
On the server where I have an environment variable set, say database, I want the worker app to run. Otherwise, I want the main application app to run.
I basically want to run pm2 start ecosystem.config.js and let PM2 decide which of the applications to start based on the system's environment variables. How can I achieve this?

pm2 script execution path is incorrect, doesn't match the one in ecosystem.config.js

My ecosystem.config.js looks like this:
module.exports = {
apps: [{
name: 'production',
script: '/home/username/sites/Website/source/server.js',
env: { NODE_ENV: 'PRODUCTION' },
args: '--run-server'
}, {
name: 'staging',
script: '/home/username/sites/WebsiteStaging/source/server.js',
env: { NODE_ENV: 'STAGING' },
args: '--run-server'
}],
deploy: {
production: {
user: 'username',
host: ['XXX.XXX.XX.XXX'],
ref: 'origin/production',
repo: 'git#github.com:ghuser/Website.git',
path: '/home/username/sites/Website',
'post-deploy': 'npm install && pm2 reload ecosystem.config.js --only production',
env: { NODE_ENV: 'PRODUCTION' }
},
staging: {
user: 'username',
host: ['XXX.XXX.XX.XXX'],
ref: 'origin/staging',
repo: 'git#github.com:ghuser/Website.git',
path: '/home/username/sites/WebsiteStaging',
'post-deploy': 'npm install && pm2 reload ecosystem.config.js --only staging',
env: { NODE_ENV: 'STAGING' }
}
}
};
When I deploy the application, I expect to see two processes - one called 'production' and one called 'staging'. These run code from the same repo, but from different branches.
I do see two processes, however, when I run pm2 desc production I can see that the script path is /home/username/sites/WebsiteStaging/source/server.js. This path should be /home/username/sites/Website/source/server.js as per the config file.
I've tried setting the script to ./server.js and using the cwd parameter but the result has been the same.
The deploy commands I am using are pm2 deploy production and pm2 deploy staging and I have verified that both the Website and the WebsiteStaging folders are present on my server.
Is there something I'm missing here? Why would it be defaulting to the staging folder like this?
What worked for me was to delete the pm2 application and start it.
pm2 delete production
pm2 start production
When I ran pm2 desc production, I saw that the script path was incorrect, and nothing I did seemed to correct that path, short of the above.
I had the same issue.
Seems it happend due to old dump.pm2 that was not updated after changes to ecosystem.config.js were made.
Updating the startup script solved the issue
pm2 save
pm2 unstartup
pm2 startup

My meanjs server takes 3-6 minutes to start

My mean.js app is based off the yoeman meanjs generator, with some tweaks (e.g. separating the front end and backend so they can be deployed separately).
I'm launching the app using fig (see fig.yml below).
When I set the command to "node server.js", the server takes 6 seconds to starts.
When I startup using "grunt", which runs nodemon and watch, it takes about 6 minutes. I've tried various things but can't really understand why nodemon would cause things to run so much slower
fig.yml:
web:
build: .
links:
- db:mongo.local
ports:
- "3000:3000"
volumes:
- .:/home/abilitie
command: grunt
#command: node server.js # much faster but you don't get the restart stuff
environment:
NODE_ENV: development
db:
image: dockerfile/mongodb
ports:
- "27017:27017"
Gruntfile (excerpt)
concurrent: {
default: ['nodemon', 'watch'],
old_default: ['nodemon', 'watch'],
debug: ['nodemon:debug', 'watch', 'node-inspector'],
options: {
logConcurrentOutput: true,
limit: 10
}
},
jshint: {
all: {
src: watchFiles.serverJS,
options: {
jshintrc: true
}
}
},
grunt.registerTask('lint', ['jshint']);
// Default task(s).
grunt.registerTask('default', ['lint', 'concurrent:default']);
It's because your first approach simply run Express server by $ node server.js. But I don't understand why i it takes 6 seconds to start? Maybe you have a slow hardware...
In order to understand why the second approach takes 6 minutes you need to understand what grunt do after launching:
Lint all this JavaScript files
serverJS: ['gruntfile.js', 'server.js', 'config/**/*.js']
clientJS: ['public/js/*.js', 'public/modules/**/*.js']
Starts two parallel processes: watch & nodemon
If watch is clear (it watching for files from stetting and after editing them restart the server) what do the nodemon? More precisely, what is the difference between starting the server by nodejs and nodemon.
From official github documentation:
nodemon will watch the files in the directory in which nodemon was started, and if any files change, nodemon will automatically restart your node application.
If you have a package.json file for your app, you can omit the main script entirely and nodemon will read the package.json for the main property and use that value as the app.
It's watching for all the files from node_modules directory and in my meanjs v0.4.0 its ~41,000 files. In your case buffering all of this files takes about 6 minutes. Try to add to your gruntfile.js grunt.initConfig > nodemon > dev > option ignore
nodemon: {
dev: {
script: 'server.js',
options: {
nodeArgs: ['--debug'],
ext: 'js,html',
watch: watchFiles.serverViews.concat(watchFiles.serverJS),
ignore: 'node_modules/*' // or '/node_modules'
}
}
},
You need to determine exactly where the problem is. Try to start the server by three different ways and to measure the time
NODE_ENV=development nodejs server.js
NODE_ENV=development nodemon server.js
NODE_ENV=development nodemon server.js --ignore node_modules/
NFS saved the day.
The VirtualBox shared folder is super slow. Using this vagrant image instead of boot2docker is much faster.
https://vagrantcloud.com/yungsang/boxes/boot2docker
Also, make sure to disable UDP, or NFS may hang. You may do so by putting this in your Vagrantfile:
config.vm.synced_folder ".", "/vagrant", type: "nfs", nfs_udp: false

Resources