PM2 keeps re-starting on Google app engine - node.js

When I run my app locally with PM2 v 3.5.0 all works fine, however when I deploy it on Google GCP app engine Flex environment, PM2 keeps restarting the app.
here are my PM2 config file
{
"apps": [{
"name" : "prod_client",
"script" : "./bin/www",
"exec_mode": "cluster_mode",
"instances": 1,
"watch" : false,
"env": {
"NODE_ENV": "production"
}
},{
"name" : "prod_api",
"script" : "./src/server/apiServer.js",
"exec_mode": "cluster_mode",
"instances": 1,
"watch" : false,
"env": {
"NODE_ENV": "production"
}
}]
}
interestingly I do not get any proper useful logs. Note here that, everything works fine in local machine, PM2 doesn't complain.

We had this same issue. It was due to PM2 trying to write files to storage, which Google AppEngine (GAE) does not generally support (more to follow on this). Also, we have not got it fully working because, sadly, there's a problem with the memory check pidusage command on GAE that has not yet been resolved [1].
So, to address the issue initially, we used the configuration to redirect logging and pidfile paths to /dev/stdout and /dev/null respectively. This got PM2 working, but it still was not working quite right. It was struggling to read the pidfile, for example.
However, GAE does allow for tmp files (we were using Standard, but I imagine Flex has similar support)[2]. So, we removed the pidfile configuration and instead, changed the start script to set PM2_HOME=/tmp/.pm2. This got us as close to working as we could, given the pidusage issue mentioned earlier.
PM2_HOME=/tmp/.pm2 pm2 start ecosystem.config.js --env production --no-daemon --mini-list
The ecosystem.config.js configuration was something like:
module.exports = {
apps: [
{
name: "service",
script: "main.js",
kill_timeout: 15000,
max_memory_restart: "400M",
exec_mode: "cluster",
instances: 1,
out_file: "/dev/stdout",
error_file: "/dev/stderr",
env: {
NODE_ENV: "development",
BLAH: "1",
},
env_production: {
NODE_ENV: "production",
BLAH: "0",
},
},
],
};

Related

PM2 Cluster Mode - Cannot find module 'dotenv/config'

I am trying to run multiple apps using PM2 in cluster mode with config file given below:
"apps": [
{
"name": "Node APIs",
"script": "./server",
"watch": true,
"node_args": "-r dotenv/config",
"instances": "max",
"exec_mode": "cluster"
},
{
"name": "Node Batch",
"script": "./batch_process",
"watch": true,
"node_args": "-r dotenv/config"
}
]
}
Node APIs process is getting errored in pm2 list while Node Batch Process works fine. When I check ~/.pm2/pm2.logs it says:
Cannot find module 'dotenv/config'
I have installed dotenv module both locally and globally but still showing same error.
Also PM2 cluster mode works fine in my local machine but on AWS EC2 it shows above error. What am I missing?
PM2: v4.4.0
NodeJS: v8.12.0
After ages of looking and experimenting, it seems that it doesn't work in cluster mode, but it does in fork mode. Try running it in fork mode.
Try specifying the full path to your package in node_modules via the node_args parameter, even if you are already specifying it in cwd.
It will work in cluster mode.
{
name: 'app-api',
script: '/full/path/to/app/api.js',
instances: 2,
exec_mode: 'cluster',
cwd: '/full/path/to/app',
node_args: ['-r', '/full/path/to/app/node_modules/dotenv/config'],
}

Run PM2 Docker with specific environment

I have been trying to pass the environment to my PM2 process so that I can target development or production.
My Dockerfile is the following:
FROM keymetrics/pm2:latest
COPY dist dist/
COPY pm2.json .
CMD ["pm2-runtime", "start", "pm2.json"]
I have the following pm2.json:
{
"name": "my-app",
"script": "dist/server.js",
"instances": "1",
"env": {
"NODE_ENV": "development"
},
"env_production" : {
"NODE_ENV": "production"
}
}
And I couldn't manage to get the environment set properly so when I access process.env.NODE_ENV I always get "none" back.
I have tried changing the CMD to:
CMD ["pm2-runtime", "start", "pm2.json", "--env", "production"] and no joy.
I have also tried to get the environment variable set in the dockerfile like this:
ENV NODE_ENV=production and that's not picked up either.
I have also checked the latest PM2 documentation and swapped the pm2.json with a ecosystem.config.js with pretty much the same structure but that hasn't work either.
What am I missing? I'm sure that has to be something really easy to fix but can't get it to work.
THanks
CMD [ "pm2-runtime", "start", "ecosystem.config.js", "--env=production"] is working for me.

pm2 start in subdirectory

I have a script in package.json like this. To run with npm I would just do it with npm start.
"scripts": {
"start": "cd build && node main"
}
I am currently trying to setup a pm2 config file for this. I created a ecosystem.json file. Neither of both of the following work with pm2 ecosystem command. What am I doing it wrong?
Note that it work if i manually type cd build && pm2 start main.js in command but this is not something i want.
First configuration:
{
"apps": [{
"name": "my-app",
"cwd": "build",
"script": "main.js"
}]
}
Second configuration
{
"apps": [
{
"name": "my-app",
"script": "npm",
"args" : "start"
}
]
}
In your code, you are giving the path incorrectly.
Use following instructions:
Hit pm2 ecosystem command, this will create a new file by name ecosystem.config.js
Remove all the code from the file and add the following code.
module.exports = {
apps : [
{
name : 'API',
script : 'build/main.js',
}
]
};
Hit pm2 start ecosystem.config.js
Check the logs using pm2 logs, your app will be started.
Hope this helps you.

How to make PM2 reload a node_modules sub-folder

I have a NodeJS app my-project, that has a module my-module as a dependency. Currently, whenever I make changes to my-module, I have to ctrl + C to quit PM2, and type pm2 start ... to start up my-project again.
This is my pm2 config file. As you can see, watch is already enabled; However, unless I quit and restart, the changes are not reflected.
{
"name": "my-project",
"script": "dist/index.js",
"watch": ["src", "../my-module/src"],
"ignore_watch": [
"node_modules"
],
"env": {
"NODE_ENV": "development",
"PORT": 8000
},
"watch_options": {
"followSymlinks": false
}
}
Is there a way to make it so that if I make changes to my-modules, they are reflected by the watch option, rather than manual restart?

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

Resources