node exec command doesn't run under pm2 - node.js

I have a very simple node script that waits for an event and then runs an ssh command:
function buildSite(){
exec('/usr/bin/ssh user#server \' cd SiteDir; ./build.sh \' ', function(error, stdout, stderr) {
console.log(stdout)
}); }
If the app is running with nodemon, this works. If I start the app with PM2, I get an event that tells me the command was received, but the site wasn't rebuilt as expected.
Am I missing something and need to accommodate for PM2?

Related

Restart an external process from within a nodejs app (linux)

Say that I am running a process from the command line (NOT a nodejs app):
myProcess doSomething --withParam1
I am also running a nodejs app that connects to this process (rpc).
node myApp
myProcess will randomly silently fail to work properly without crashing and myApp will detect it. I need myApp to be able to restart myProcess (kill it and start it again). After I restarted myProcess, myApp will also restart itself using pm2 (I am already handling the pm2 restart part for the nodejs app - my issue is that I cannot use pm2 to restart myProcess since it is not a nodejs app). Also, I cannot change the code of myProcess since it is a 3rd party software.
How can I restart the external process from my nodejs app?
I ended up using process.kill to kill the process and nodejs child process to restart it.
To find the pid of the process before killing it, I used this:
const childProcess = require('child_process');
function printPid() {
childProcess.exec('pidof -s myProcess', function(error, stdout, stderr) {
if (error) {
console.log(error);
} else {
console.log(stdout);
}
});
}

How can I run grunt as a daemon?

I am running a packaged nodejs webserver that allows for reading of epub files (Readium-JS), and it is started with the grunt command.
However, if I run this on my VPS the server dies as soon as my terminal connection ends.
How can I run this task as a daemon?
I have looked at options like grunt-forever and grunt-daemon but the way the Gruntfile is written using load-grunt-config is messing with my mind and I can't piece together how to isolate the server code.
Here's the solution I found:
As was suggested above, using pm2
However, when I ran
pm2 start grunt
I got an error saying that the grunt module did not exist, which was weird.
So I ended up writing a script which worked:
-- start.js --
var pm2 = require('pm2');
pm2.connect(function() {
pm2.start({
script : '/usr/local/bin/grunt', // Script to be run
args: '--force',
}, function(err, apps) {
pm2.disconnect();
});
});
After running node start.js from the command line, everything sailed smoothly.

Grunt exec running a node command in background

I'm trying to run grunt with a js script. The script start up a server that should be listening all the time in background. To it I'm using grunt and grunt-exec, and my exec.js is like that
start: {
cmd: function () {
var start = 'node server.js &';
console.info('Starting');
return start;
}
}
When I run grunt exec:start the process finish but the server is not running.
Same command without '&' works but it's not the wanted.
I've tried to move the command to a bash but the result is the same, the server is never started when the character '&' is added, neither in the .sh nor in the grunt-exec command.
Finally I solved it changing the command:
var start = "nohup node server.js";
I.t seems run in background properly.

Callback never called in child_process.exec with redis

I am trying to start redis from node using the child_process module with the following code:
var childProcess = require('child_process');
childProcess.exec('redis-server --port 6380', function(err, stdout, stderr) {
console.log(err, stdout, stderr);
})
When I run it, the callback is never called. I can see that my redis-server has started on port 6380 using ps auwx | grep redis-server so I don't get why this callback is not called.
Note that when I run redis-server --port 6380 in my terminal, redis starts just fine as well.
I've tried this with memcached instead and it works fine.
What is the reason why this callback is not called?
Many thanks
Because the callback is called only when the process terminates.
If you need to check whether the redis process has finished initializing you can use spawn with event handlers for stdout.

How can I restart a Node.js app from within itself (programmatically)?

How can I create an app that can restart itself? I want to create an app that sets up a web-admin which can restart itself. Is this possible? If so, how? I was thinking this might be possible with the process global variable that is built into node.
LK"I
It is possible without external dependencies:
console.log("This is pid " + process.pid);
setTimeout(function () {
process.on("exit", function () {
require("child_process").spawn(process.argv.shift(), process.argv, {
cwd: process.cwd(),
detached : true,
stdio: "inherit"
});
});
process.exit();
}, 5000);
source : https://gist.github.com/silverwind/d0802f7a919ae86ff25e
I have run Forever several times and it is easy to get started with. Check it out at: https://github.com/nodejitsu/forever
I know it's a little late to reply however I had a similar requirement. I wanted to restart my node process whenever I made a configuration change. I'm using pm2 to manage my node processes so it turned out to be really easy.
After making a configuration change, i execute process.exit() from within the node process. As far as I can see, the process exits then pm2 restarts the process fine.
Not sure yet if there are any side effects but it seems to be working fine for me right now.
you can run your app using child process and manipulate it how needed:
https://nodejs.org/api/child_process.html
use forever, pm2 or whatever thing to restart after death and kill itself with process.exit() https://nodejs.org/api/process.html
Not from the process itself but it might be useful to people that land on here.
I add it to systemd of Linux and it starts up on network.target logs the console to /var/logs/<app>.log and it restarts on failure. So you can just force a process.exit on it.
sudo touch /lib/systemd/system/<app>.service
sudo tee -a /lib/systemd/system/<app>.service > /dev/null <<EOT
[Unit]
Description=<app>
After=network.target
[Service]
Type=simple
User=$USER
ExecStart=/bin/node --prefix /home/$USER/path/to/app
Restart=on-failure # or always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=<app>
[Install]
WantedBy=multi-user.target
EOT
sudo touch /etc/rsyslog.d/<app>.conf
sudo tee -a /etc/rsyslog.d/<app>.conf > /dev/null <<EOT
if $programname == '<app>' then /var/log/<app>.log
& stop
EOT
sudo systemctl enable <app>
sudo systemctl daemon-reload
sudo systemctl restart rsyslog
sudo systemctl start <app>
i know the question is a little old but it may help someone later :
i would suggest to use nodeJS Cluster & Worker for this purpose!
const cluster = require('cluster');
if (cluster.isMaster ?? cluster.isPrimary) {
cluster.fork();
cluster.on("exit", (worker, code) => {
console.log(`[master] worker #${worker.id} down, restarting\n`);
cluster.fork();
});
process.on("SIGINT", () => { });
} else {
console.log(`\nnew worker #${cluster.worker.id}\n`);
process.on("SIGINT", () => {
console.log(`[worker#${cluster.worker.id}] SIGINT received! dying gracefully!!\n`);
process.exit(0);
});
}
try running it with nodejs and hitting the ctrl+c combination.
it will just restart with the new code running.
you can kill the master with sending any signal other than SIGINT
create file nodemon.sh
#!/usr/bin/env bash
while true; do
sleep 20
echo "// nodemon $(date)" >config.js
done
permition sudo chmod +x nodemon.sh
run it
./nodemon.sh
Yes, upstart will restart your process without a nodemon.
npm install -g nodemon
sudo nodemon server.js
nodemon will watch the files in the directory that nodemon was started, and if they change, it will automatically restart your node application.

Resources