Update Nodejs App launched with Pm2 as Windows Service - javascript

I'm writing an small application in nodejs.
This app should be executed as windows service (so I can't use electron or others because It should be active even if the user is not logged), and so I have thought to use PM2.
It starts and works fine, but my problem, now, are the updates of my NodeJS app.
My app will released to many PC and I don't want update it one by one.
Yes, I have a repository where I can read and so I can create in my app a function where with established interval I go to my repo and pull.
For now I have created, in packages.json of my NodeJs app a scripts command like:
git pull //myrepourl.git origin
And in my index.js a function like:
function updateApp(){
return new Promise((resolve,reject)=>{
exec('cd app_path && npm run prod_update', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
reject();
}
resolve();
});
})
}
setInterval( ()=>{
updateApp();
console.log("------ Updated ---------")
},60*60*1000);
But this way don't convince me because actually my repo is private and then I have to expose my credentials git in app, whithout considering the problem of node_modules.
So are there others way to update a Nodejs app launched with PM2 as Service on Windows?

Related

How to run child_process.exec correctly on an ajax request?

There is a server, that I have an access to, but do not have ownership on. It serves a node js / express application on a default port 3000. There are several scripts, that are usually run either manually from the terminal or by cron job. What I want to do is to have a button on the client-side and make an ajax request to a certain route and execute a node js command with inline arguments. For example:
node script.js 123
All routes are set and working. I have a CliController file that handles requests and has to run the command above. Currently I am using the following code:
cp.exec(`node script.js ${ip}`, function (err, stdout, stderr) {
if (err) {
console.log(err);
}
console.log(stdout);
console.log(stderr);
});
The script.js file is in root folder of the project, but the project itself was built by using express-generator and is being served using node bin/www command. There is a service/process on the server that runs nodemon to restart this project if it fails as well. Therefore I do not have access to output of that particular process.
If I run the command above in the terminal (from the root folder of the project, to be precise), it works fine and I see the output of the script. But if I press the button on the webpage to make a request, I am pretty sure that the script does not execute, because it has to make an update to database and I do not see any changes. I also tried to use child_process.spawn and child_process.fork and failed to get it working.
I also tried to kill nodemon and quickly start the project again to the see console output. If I do this, everything works.
What am I doing wrong ?
The process invoked may be in a blocking state, hence the parent script is simply waiting for the children process to terminate, or return something.
We can avoid this behaviour right into the shell command, by adding & (ampersand control operator) at the end.
This makes a command running in the background. (Notice, you can still control the children(s) process using the PID's and POSIX signals, this is another subject, but very related and you might find it very handy pretty soon).
Also notice that killing/stopping the parent script will also kill the children(s). This can be avoided using nohup.
This is not linked to JavaScript or node.js, but to bash, and can be used with anything in the shell.
cp.exec(`node script.js ${ip} &`, function (err, stdout, stderr) {
if (err) {
console.log(err);
}
console.log(stdout);
console.log(stderr);
});
Bash reference manual

How to run python script from nodejs on heroku

I am basically working on a NodeJS app that has some buttons and on clicking them I run some python machine learning and deep learning models but the problem is that I cant install basic python libraries like numpy. Also as soon as I add python build pack to my app it stops running. The logs show that there is no web process. I found in docs that we have to insert a Procfile.txt with npm commands but that also didn't solve the problem.
The whole setup runs perfectly on the local machine.
you need use child_process;
const { exec } = require("child_process");
exec("python path/to/the/python_script.py", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
https://stackabuse.com/executing-shell-commands-with-node-js/
Or you can use for this npm library python
#Vladim Hulevich Thanks for replying. But I ran it like this only and it works like a charm on my local machine but when I run my script on heroku it produces error of numpy not found. But my app is basically nodejs so I only added nodejs buildpack and not python as when I add python buildpack my nodejs app also stops running

How to Install and manage a windows service in a node js app.?

I have a windows service, i need to install it and manage it using my electron app. What is the best way to do this?
Thanks.
update
Currently for installing a service i need to use
Installutil (path of my service)
And for starting net start myservice
Need to do this while installing my electron app.
Related to this post Stop and Start a service via batch or cmd file?
You can do exec with child process as example
const {exec} = require('child_process');
exec('YOUR TERMINAL CODE HERE', (err, stdout, stderr) => {
//..
});

How to get the runtime url of sails app within mocha tests

I'm aware of sails.getBaseUrl and the fact that it is deprecated. In the bootstrap.test.js while doing a sails lift I specify a port: 1337. sails.getBaseUrl() returns http://localhost:1337. I then run the tests using mocha (from within WebStorm if that matters). At the same time I'm able to do a sails lift at the terminal and run the same sails app on http://localhost:1337. Both seem to be running fine without a port conflict.
So at what location is mocha running the sails app when running the tests?
If you're not setting it to something else, then your Sails app is starting on port 1337. I'd check that you don't have a PORT environment variable set somewhere that one or the other app is using to override the default. Unless one of the apps is running in a virtual machine like Docker, it's not possible for both of them to be running on port 1337 without conflict, so either your tests are failing silently or they're running a different port.
In Sails v0.12.x and Sails v1.0, the HTTP server is available as sails.hooks.http.server, so you should be able to check the port that an app is listening on with sails.hooks.http.server.address().port.
The issue was that our tests were doing a sails load and not a sails lift. Based on the sails lift and load documentation and the source code I figured out that the port binding is not done in sails load. So I just added extra code for binding/unbinding the port as part of the test lifecycle.
before(function (done) {
server = sails.hooks.http.server.listen(sails.config.port, function (err) {
if (err) {
return done(err);
}
return done();
});
});
after(function (done) {
server.close();
done();
});

How to keep my node js server alive

I have created an app in Node js including with express js and I will execute the app using the command prompt
c:/myApp > npm start
And it is running my app, but whenever I closed the prompt the server is closing.I have tried with forever like
> npm install forever -g
> forever start --minUptime 1000 --spinSleepTime 1000 app.js
but it is not working either.Is there any way to keep the connection alive.Thanks in advance.
I've used forever for about 3 years. It sucks. It has a ton of bugs and BS that hasn't been fixed after a long time.
I've switched to pm2. It has a much better CLI and API, and a lot less bugs.
CLI:
pm2 start app.js
API:
var pm2 = require('pm2')
pm2.connect(function(err) {
pm2.start({
script: 'runningTest.js'
}, function(err, apps) {
if(err) console.log(err)
pm2.disconnect()
})
})
I use this instruction (Nginx + supervisord) for my projects in production:
http://cuppster.com/2011/05/12/diy-node-js-server-on-amazon-ec2/
Start read from chapter "Have Your Node Server Run Forever"

Categories