PM2 Cluster Mode - Cannot find module 'dotenv/config' - node.js

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'],
}

Related

What could be affecting my Node.JS environment that does not allow me to debug my JS with babel-node?

I have a Node JS server written with ES6 features and use Babel to transpile the code for production. The code itself complies and works fine. I am also able to run my "dev" server and test it locally with this command:
npm run dev
which runs this command inside my package.json:
"dev": "nodemon --exec babel-node ./src/server.js"
Pretty standard so far.
I am having issues with debugging my code so I can use breakpoints. Here's the launch script in my VS Code launch.json file:
{
"name": "Debug",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/src/server.js",
"stopOnEntry": false,
"sourceMaps": true,
"args": [],
"preLaunchTask": null,
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/babel-node",
"runtimeArgs": ["--no-lazy"],
"env": {
"NODE_ENV": "development"
},
"skipFiles": [
"${workspaceFolder}/node_modules/**/*.js",
"<node_internals>/**/*.js"
]
}
And my .babelrc file:
{
"presets": [
[
"#babel/env",
{
"targets": {
"node": "current"
}
}
]
],
"env": {
"development": {
"sourceMaps": "inline",
"retainLines": true
}
},
"comments": true,
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-object-rest-spread"
]
}
When I try to enter debug mode I get this execption thrown right away:
Exception has occurred: Error: Cannot find module 'kexec'
Require stack:
- F:\Dev\Web Development\****\dev\server\node_modules\#babel\node\lib\babel-node.js
- F:\Dev\Web Development\****\dev\server\node_modules\#babel\node\bin\babel-node.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:956:15)
at Function.Module._load (node:internal/modules/cjs/loader:804:27)
at Module.require (node:internal/modules/cjs/loader:1028:19)
at require (node:internal/modules/cjs/helpers:102:18)
at F:\Dev\Web Development\****\dev\server\node_modules\#babel\node\lib\babel-node.js:65:68
at processTicksAndRejections (node:internal/process/task_queues:96:5)
This is where is gets really odd. I pulled the same sourcecode to my laptop and debugging worked just fine. I also spun up a sandbox virtual machine on my Windows 10, did a clean install of Node + VS Code on it, and it worked perfectly there too.
There's something in my current environment that is causing this issue and I cannot figure it out. I've been trying to solve this issue for a few days now with no success.
Here are the steps I have already taken:
Upgrade and downgrade versions of Node + NPM and retry using
different versions
Delete node_modules and reinstall with "npm install" (and using npm ci)
Completely uninstall Node and do a fresh install
Removed user and system environemnt variables before the fresh install
Manually delete all NPM caches from %AppData% folder
I also want to point out that when I used a different launch script that is attached to a process ID, I was able to debug the code, but I am trying to streamline this process instead of having to choose the process each time.
This method does work:
npm run dev to start the dev server, which runs this code:
"dev": "nodemon --exec babel-node ./src/server.js"
I then run the debugger and attach it to the running process. Here's the launch script for that:
{
"name": "Attach by Process ID",
"processId": "${command:PickProcess}",
"request": "attach",
"skipFiles": ["<node_internals>/**"],
"type": "node"
}
If kexec is used by Babel, isn't it already supposed to be installed as a dependecy? I couldn't find it anywhere in my modules folder though.
I also tried installing kexec separately but was receiving a lot of node-gyp errors which I tried fixing by reinstalling all of Node build tools using multiple different methods. None of these actions also fixed the issue.
Any ideas or support would tremendously help at this point.

PM2 keeps re-starting on Google app engine

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",
},
},
],
};

Why would Jest test randomly fail if not in watch mode?

I'm having a weird problem. If I run
jest --watch
via npm, everything works as expected.
If I turn on coverage, then I get random errors, mostly like this
ENOENT: no such file or directory, lstat
More details
The command that is reliable is defined in package.json as:
"test": "jest --watch --config jest-watch.json",
The command that is not reliable is
"test-all": "jest"
We use a jest.config.js file:
module.exports = {
verbose: false,
testURL: 'http://localhost/',
coverageReporters: ['json', 'lcov', 'html'],
collectCoverageFrom: [
'<rootDir>/src/**/*.{js,jsx}',
'!**/node_modules/**',
'!**/vendor/**',
'!**/coverage/**',
'!<rootDir>/lambda.js',
'!<rootDir>/server.js'
],
collectCoverage: true,
coverageThreshold: {
global: {
statements: 40,
branches: 17,
functions: 18,
lines: 41
}
},
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
testPathIgnorePatterns: ['<rootDir>/lambda.js', '<rootDir>/server.js']
};
and the `jest-watch.config' file is:
{
"collectCoverage": false,
"setupFilesAfterEnv": ["<rootDir>/setupTests.js"]
}
This is happening in every project I use jest, both node and react apps. However, I have about 10+ teammates, some on Windows and some on Macs and nobody else is having this problem. I believe I'm the only one using WSL (Windows Subsystem for Linux).
I'm running Windows 10 1803. I'm using Ubuntu as my Linux distro.
Any ideas on what could be causing this?
I don't test it, but your configuration looks fine, I've some question:
1- Do you use jest Global or local in your project?
2- What happened when you run inside the project folder "npm run test"?
3- have you tried to run "jest --watch" inside the project folder?
Note: Because you're using WSL you should check your bash configuration, your shell, and your $PATH environment variable.

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.

chef setup: trying to start node app with PM2

I'm using the nodejs cookbook to install node and PM2 module.
include_recipe "nodejs"
nodejs_npm "pm2"
So far, so good. But when I try to start my node app via PM2 with a process.json file it starts but isn't listed in the PM2 output when I ssh into the machine and run pm2 list ... very irritating.
Am I doing something wrong is it correct to not show up there?
execute "start node app via PM2" do
cwd "/share/app"
command "pm2 startOrRestart process.json"
end
and the process.json looks like this:
{
"apps": [
{
"name": "app",
"script": "src/index.js",
"watch": true,
"ignore_watch": ["[\\/\\\\]\\./", "node_modules"],
"merge_logs": true,
"exec_interpreter": "node",
"env": {
"NODE_ENV": "local",
"port": 8080
}
}
]
}
It's because you started the process.json with another user, then when you ssh and do a pm2 list, it only list your current process users.
To avoid that you have two choices:
Do the pm2 start process.json with the same user
Set the PM2_HOME environment variable so all users will hit the same PM2 instance. Eg PM2_HOME='/etc/.pm2' pm2 start process.json && PM2_HOME='/etc/.pm2' pm2 list

Resources