Restarting nodejs server on crashing in an electronjs app - node.js

I am building an electron app and using nodejs as the backend server within the app.
How can I auto-restart the nodejs server if it encounters a crash?
I am currently using pm2 and using the following code in electron's main.js file
var pm2 = require("pm2");
pm2.connect(function(err) {
if (err) {
console.error(err);
process.exit(2);
}
pm2.start(
{
name: "mydesktopapp",
script: "./server/server.js", // nodejs Script to be run
exec_mode: "cluster",
instances: 1,
max_memory_restart: "5000M", // Optional: Restarts your app if it reaches 5GB
noDaemonMode: true,
watch: true
},
function(err, apps) {
pm2.disconnect(); // Disconnects from PM2
console.error(`Unable to start PM2: ${err}`);
if (err) throw err;
}
);
});
But this does not seem to work, as its throwing the following error:
Unable to start PM2: null
How do you guys handle this?
Thanks

Related

Start nestjs project as a Windows service

We used to start Angular and NestJS (based on node.js) projects using Docker containers. This solution was discontinued for various reasons, so we are looking for a way to start these projects at the start of the PC (or on a trigger) and restart the project automatically if a crash occurs.
node-windows
This package builds a Windows service from a node.js project. NestJS being based on node.js, starting it using node.js is done this way (while in the project's folder):
node PATH_TO_PROJECT\node_modules\#nestjs\cli\bin\nest.js start --config .\tsconfig.build.json
The script used:
const svc = new Service({
name: 'Test',
description: 'Test',
script:
'PATH_TO_PROJECT\\node_modules\\#nestjs\\cli\\bin\\nest.js',
scriptOptions: [
'start --watch --config PATH_TO_PROJECT\\tsconfig.build.json',
],
],
execPath: 'C:\\Program Files\\nodejs\\node.exe',
});
svc.on('install', function () {
console.log('installed');
svc.start();
});
svc.install();
The installation works as intended but in a browser, the server cannot be reached.
Questions
Is there a way to use node-windows for a NestJS project?
Is it possible to use an absolute path with the nest cli start command? (e.g nest start --config ABSOLUTE_PATH)
How would you start an Angular project the same way?
Thank you.
am use 'child_process' lib for run command
like this
server.js
const { exec } = require("child_process");
exec("npm run start", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
and use node-windows like this
var Service = require('node-windows').Service;
var serviceDetail = require('./servicename')();
console.log(serviceDetail);
// Create a new service object
var svc = new Service({
name: serviceDetail.name,
description: serviceDetail.detail,
script: './server.js'
});
console.log('start building up service name ' + serviceDetail.name);
// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on('install',function(){
svc.start();
});
svc.install();

Why Google Cloud Run gettings massive container restart / new instance creation?

I've been using Google Cloud Run for a year now and the issue with cloud run containers restarts / new container start is from the beginning.
I've hosted Node + MongoDB app in Cloud Run, but cloud run container is restarting frequently. It's getting around 10 - 12 requests / second, couldn't find any performance bottleneck, requests are serving smoothly, sometimes requests are served more than normal time, might be new container instance cold start delay.
The issue I am facing is the HIGH Number of connections to the MONGODB Server. After some research I could find that I've to close mongodb connection on node process exit so I've added a graceful shutdown function.
// Function to terminate the app gracefully:
const gracefulShutdown = async () => {
console.log(`MONGODB CONNECTION CLOSED!`);
await mongoose.connection.close();
};
// This will handle process.exit():
process.on('exit', gracefulShutdown);
// This will handle kill commands, such as CTRL+C:
process.on('SIGINT', gracefulShutdown);
process.on('SIGTERM', gracefulShutdown);
// This will prevent dirty exit on code-fault crashes:
process.on('uncaughtException', gracefulShutdown);
But even after adding this, I couldn't find this graceful shutdown function is invoked while checking logs.
Does google cloud run really signals when the nodejs process in the container crashed?
Is there any way to identity a container restart or new instance creation in cloud run?
Here is the MongoDB connection code
exports.connect = () => {
try {
mongoose
.connect(MONGO.URI, {
useCreateIndex: true,
keepAlive: 1,
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
})
.then((docs) => {
console.log(`DB Connected`);
})
.catch((err) => {
console.log(`err`, err);
});
return mongoose.connection;
} catch (err) {
console.log(`#### Error Connecting DB`, err);
console.log(`Mongo URI: `, MONGO.URI);
}
};
Sometimes cloud run issues a high number of connections to MONGODB, and hits the connection limit of 1500 connections.
Any suggestions are appreciated! I've been facing this issue for a year now.
You should not start the node process using npm or yarn but directly as CMD ["node", "index.js"] (when you are inside a Docker container using Dockerfile)
Explanation here https://maximorlov.com/process-signals-inside-docker-containers/

MongoDB not authorized error on Ubuntu 16.04

I am installing a server on Digitalocean and have a MongoDB issue. I installed Mongo on the server and allowed remote access.
I created two users. One is super-user for me and the other is a regular user for the website users. I am able to connect to the mongo through Robomongo 3T (a mongo client) remotely for both users.
However, when I use the application from a browser, a simple login request gives an authentication error. Here is the error:
MongoError: not authorized on DATABASE_NAME to execute command { find: "users", filter: { email: "YYY", password: "XXX" }, limit: 1, singleBatch: true, batchSize: 1 }
Here is the realted server-side code:
Connecting the database at server.js:
MongoClient.connect(config.mongo_url, (err, client) => {
if(err) throw err
console.log('db connected')
app.locals.db = client
// start the server
app.listen(process.env.PORT || 3000, ()=>console.log('listening on port 3000!'))
});
Trying to connect to the local mongo on the server:
database.collection(config.mongo_col_user)
.findOne({
email: username,
password: hash
}, (err, user)=>{
if(err) return done(err)
if(!user) return done(null, false, {msg: 'not found'})
if(user.password)
return done(null, user)
})
I use pm2 on the server side and I use ecosystem.config.js which has the below code:
module.exports = {
apps : [
{
name: "NAME",
script: "SCRIPT_NAME",
watch: true,
env: {
"mongo_url": 'mongodb://USER_NAME:PASSWORD#localhost:27017?authMechanism=SCRAM-SHA-1&authSource=DATABASE_NAME',
"mongo_db_name": 'DATABASE_NAME',
"mongo_col_query": "COLLECTION_NAME",
}
}
]
}
Could you help with the problem please?
I have figured it out.
When I did make changes to pm2 environment file ecosystem.config.js, I did always restart pm2 with pm2 restart all. However, when you change the file, you should tell pm2 that you changed it by pm2 reload ecosystem.config.js --update-env.
Additionally, the correct syntax is no
mongodb://USER_NAME:PASSWORD#localhost:27017?authMechanism=SCRAM-SHA-1&authSource=DATABASE_NAME'
but
mongodb://USER_NAME:PASSWORD#localhost:27017/DATABASE_NAME'

API HOST name from env variable node js

I have got a react app where I need to dynamically pass the API HOST name from environment (docker run --env API_HOST=localhost)
I'm using a child process in gulp to run 'node node.js'
//run npm install then node app
cp.spawn('npm install' ,{cwd:NODE_APP_FOLDER,env:process.env}, function(error, stdout, stderr) {
if (error) {
console.error(`exec error: ${error}`);
return;
}
var server = cp.spawn('node', ['app.js'], {
cwd: NODE_APP_FOLDER,
env: {
API_HOST:'localhost'
}
});
}
but in my code within the app process.env.API_HOST return undefined
Any help would be much appreciated

Babel not working with Mocha and starting Node server

I am running sailsjs, mocha, and babel on sails and mocha. When I run, my before function to start the sails app before running tests, I get this:
> PORT=9999 NODE_ENV=test mocha --recursive --compilers js:babel/register
lifting sails
1) "before all" hook
0 passing (757ms)
1 failing
1) "before all" hook:
Uncaught Error: only one instance of babel/polyfill is allowed
For the life of me, I can't figure out how to make mocha running babel and sails running babel at the same time work.
My before() code looks like this:
import Sails from 'sails'
// Global before hook
before(function (done) {
console.log('lifting sails')
// Lift Sails with test database
Sails.lift({
log: {
level: 'error'
},
models: {
connection: 'testMongoServer',
migrate: 'drop'
},
hooks: {
// sails-hook-babel: false
babel: false
}
}, function(err) {
if (err) {
return done(err);
}
// Anything else you need to set up
// ...
console.log('successfully lifted sails')
done();
});
});
I use sails-hook-babel and it works like a charm. Here to do it:
Install npm install sails-hook-babel --save-dev
Edit your bootstrap.js/ before function to load babel, i.e.
var Sails = require('sails'),
sails;
var options = {
loose : "all",
stage : 2,
ignore : null,
only : null,
extensions: null
};
global.babel = require("sails-hook-babel/node_modules/babel/register")(options);
before(function (done) {
Sails.lift({
//put your test only config here
}, function (err, server) {
sails = server;
if (err) return done(err);
// here you can load fixtures, etc.
done(err, sails);
});
});
after(function (done) {
// here you can clear fixtures, etc.
sails.lower(done);
});
Now you are able to use ES6 within your tests.
Here is the reference:
Babel issue at GitHub
My Blog, sorry it written in Bahasa Indonesia, use Google translate if you want to.

Resources