How to run node js server as a daemon process? - linux

I am using Ionic framework and nodejs for one app. All nodejs files are in linux server. I am starting the nodejs server using 'npm start &' command through putty. But the problem is if I close putty the server is getting stopped after sometime. I tried 'nohup npm start &'. But still I am facing the same issue. How to start this as a daemon process..?

You can use pm2 for production.
To install pm2 :
npm install pm2 -g
To start an application simply just run :
pm2 start app.js
You can check logs via:
pm2 logs
For more options just checkout their readme files on github repo.

This is adaptation of daemon module:
const child_process = require('child_process')
function child(exe, args, env) {
const child = child_process.spawn(exe, args, {
detached: true,
stdio: ['ignore', 'ignore', 'ignore'],
env: env
})
child.unref()
return child
}
module.exports = function(nodeBin) {
console.log('Daemonize process')
if (process.env.__daemon) {
return process.pid
}
process.env.__daemon = true
var args = [].concat(process.argv)
var node = args.shift()
var env = process.env
child(node, args, env)
return process.exit()
}
Usage:
const daemon = require('daemon')
daemon()
app.listen(...)
https://wiki.unix7.org/node/daemon-sample

For creating true daemons (a process not attached to any tty) you can use one of the several daemon modules available on npm.
A quick search gave me this: https://www.npmjs.com/package/daemon
Interestingly, the module above works using pure javascript and node.js built-in modules without requiring any C extensions. It works by exploiting how child_process works in newer versions of node (> 0.9).

either use PM2/forever & nginx for managing the services well. [RECOMMENDED]
or you can run by the default OS services. I'm using ubuntu 20.04 amd64 on ec2-t2.micro and everything is preinstall with image.
# TO Run the service on port 80 as deamon thread
sudo PORT=80 nohup node server.js &
#To run the service on 3000 port and point to 80.
PORT=3000 nohup node server.js &
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000
# to kill the process run
ps -ef | grep "node"
kill -9 <pid>

Related

How can a NodeJS app restart itself as sudo?

I've got a NodeJS app that needs to run as superuser. The user running this (should) have sudo privileges. Therefore they can easily run the app with "sudo node ...". For convenience, I would like the app to restart itself with sudo if it's not running as root.
Reading NodeJs execute command in background and forget, I have tried the following:
const isroot = process.getuid && process.getuid() === 0;
if (!isroot) {
console.log("Must be running as superuser! Restarting with sudo.");
spawn("sudo", process.argv, {
stdio: "inherit",
detached: true
}).unref();
process.exit(0);
}
However, this doesn't work as the user needs to enter their password and, despite setting stdio to inherit, I get the error:
sudo: no tty present and no askpass program specified
Can anyone see what I'm doing wrong, and is there a more obvious solution?
Thanks for any suggestions.

Why isn't my server restarting / code updating using Docker + Nodejs?

My docker file is super simple:
FROM node:4-onbuild
RUN npm install gulp -g;
EXPOSE 8888
This image will automatically run the start script in package.json which I have set simply as gulp.
If I run gulp on my host machine, and make a change to node file, it automatically restarts server:
var gulp = require('gulp');
var nodemon = require('gulp-nodemon');
gulp.task('default', function() {
nodemon({
script: 'server.js', // starts up server on port 4000
env: { 'NODE_ENV': 'development' }
})
});
Figuring everything is okay I run this: docker run -d -p 1234:4000 -v $(pwd):/usr/src/app my-image
Going to http://192.168.99.100:1234/ shows 'Hello World!' from my server.js file. Updating the file does NOT update what I see by hitting that URL again. If I exec into the container, I see the file is updated. Since the container started node via the same gulp command, I don't understand why the node server wouldn't have restarted and shown the update.
The TL;DR of this is that you need to set nodemon to poll the filesystem for changes as follows: https://github.com/remy/nodemon#application-isnt-restarting
In some networked environments (such as a container running nodemon reading across a mounted drive), you will need to use the legacyWatch: true which enabled Chokidar's polling.
Via the CLI, use either --legacy-watch or -L
The longer version is this (with one key assumption - you're using docker on Mac or similar):
On Mac or similar, docker doesn't run natively and instead runs inside of a virtual machine (generally virtual box via docker-machine). Virtual machines generally don't propagate filesystem inotify events, which is what most watchers rely on to restart or perform an action when a file changes. As the virtual machine doesn't propagate the events from the host, Docker never receives the events. Your original docker file would probably work on a native linux machine.
There's an open issue and much more detailed discussion of this here.

Code Deploy ApplicationStart gets stuck on pending using node

Hi I'm new to using Code Deploy. I am trying to launch a node application. I have setup.sh, start.sh and app.js in my root directory.
This is my appspec.yml file
version: 0.0
os: linux
files:
- source: /
destination: /
hooks:
Install:
- location: setup.sh
timeout: 3600
ApplicationStart:
- location: start.sh
timeout: 3600
setup.sh
yum -y install nodejs npm --enablerepo=epel
npm install
start.sh
node /app.js
app.js (just a basic dummy server)
var express = require("express");
var app = express();
app.get("/",function(req,res) {
res.send("Hello world")
})
var server = app.listen(8080,function() {
console.log("Listening at " + server.address().address + ": " + server.address().port);
});
The Install step successfully completes, but Code Deploy gets stuck on pending when it does the ApplicationStart step.
I'm pretty sure it's because the app.js program runs continously, so how is CodeDeploy supposed to know that it's working and move on?
The CodeDeploy agent is waiting for the script it launched to return an exit code and to close stdout and stderr. To start a process in the background and detach it from the host agent so it can run as a daemon, try:
node /app.js > /dev/null 2> /dev/null < /dev/null &
Note: you'll want to modify your program to write to a log file instead of the console, since daemons usually don't have a console to write to (as it is in this version).
See the official docs here: http://docs.aws.amazon.com/codedeploy/latest/userguide/troubleshooting.html#troubleshooting-long-running-processes
The command node /app.js does not run in background but in foreground, therefor the start.sh script is never finished.
See this thread for more info about running node in background Node.js as a background service

How to stop app that node.js express 'npm start'

You build node.js app with express v4.x then start your app by npm start. My question is how to stop the app? Is there npm stop?
EDIT to include the error when implement npm stop
/home/nodetest2# npm stop
> nodetest2#0.0.1 stop /home/nodetest2
> pkill -s SIGINT nodetest2
pkill: invalid argument for option 's' -- SIGINT
npm ERR! nodetest2#0.0.1 stop: `pkill -s SIGINT nodetest2`
npm ERR! Exit status 2
Yes, npm provides for a stop script too:
npm help npm-scripts
prestop, stop, poststop: Run by the npm stop command.
Set one of the above in your package.json, and then use npm stop
npm help npm-stop
You can make this really simple if you set in app.js,
process.title = myApp;
And, then in scripts.json,
"scripts": {
"start": "app.js"
, "stop": "pkill --signal SIGINT myApp"
}
That said, if this was me, I'd be using pm2 or something the automatically handled this on the basis of a git push.
All the other solutions here are OS dependent. An independent solution for any OS uses socket.io as follows.
package.json has two scripts:
"scripts": {
"start": "node server.js",
"stop": "node server.stop.js"
}
server.js - Your usual express stuff lives here
const express = require('express');
const app = express();
const server = http.createServer(app);
server.listen(80, () => {
console.log('HTTP server listening on port 80');
});
// Now for the socket.io stuff - NOTE THIS IS A RESTFUL HTTP SERVER
// We are only using socket.io here to respond to the npmStop signal
// To support IPC (Inter Process Communication) AKA RPC (Remote P.C.)
const io = require('socket.io')(server);
io.on('connection', (socketServer) => {
socketServer.on('npmStop', () => {
process.exit(0);
});
});
server.stop.js
const io = require('socket.io-client');
const socketClient = io.connect('http://localhost'); // Specify port if your express server is not using default port 80
socketClient.on('connect', () => {
socketClient.emit('npmStop');
setTimeout(() => {
process.exit(0);
}, 1000);
});
Test it out
npm start (to start your server as usual)
npm stop (this will now stop your running server)
The above code has not been tested (it is a cut down version of my code, my code does work) but hopefully it works as is. Either way, it provides the general direction to take if you want to use socket.io to stop your server.
On MAC OS X(/BSD):
you can try to use the lsof (list open files) command
$ sudo lsof -nPi -sTCP:LISTEN
and so
$ kill -9 3320
When I tried the suggested solution I realized that my app name was truncated. I read up on process.title in the nodejs documentation (https://nodejs.org/docs/latest/api/process.html#process_process_title) and it says
On Linux and OS X, it's limited to the size of the binary name plus the length of the command line arguments because it overwrites the argv memory.
My app does not use any arguments, so I can add this line of code to my app.js
process.title = process.argv[2];
and then add these few lines to my package.json file
"scripts": {
"start": "node app.js this-name-can-be-as-long-as-it-needs-to-be",
"stop": "killall -SIGINT this-name-can-be-as-long-as-it-needs-to-be"
},
to use really long process names. npm start and npm stop work, of course npm stop will always terminate all running processes, but that is ok for me.
Check with netstat -nptl all processes
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 1736/mongod
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1594/sshd
tcp6 0 0 :::3977 :::* LISTEN 6231/nodejs
tcp6 0 0 :::22 :::* LISTEN 1594/sshd
tcp6 0 0 :::3200 :::* LISTEN 5535/nodejs
And it simply kills the process by the PID reference.... In my case I want to stop the 6231/nodejs so I execute the following command:
kill -9 6231
This is a mintty version problem alternatively use cmd. To kill server process just run this command:
taskkill -F -IM node.exe
If you've already tried ctrl + c and it still doesn't work, you might want to try this. This has worked for me.
Run command-line as an Administrator. Then run the command below to find the processID (PID) you want to kill. Type your port number in <yourPortNumber>
netstat -ano | findstr :<yourPortNumber>
Then you execute this command after you have identified the PID.
taskkill /PID <typeYourPIDhere> /F
Kudos to #mit $ingh from http://www.callstack.in/tech/blog/windows-kill-process-by-port-number-157
kill $(lsof -t -i :PORT_TO_KILL)
simplified version. Simple copy paste with the port to kill ex.5000
For windows machine (I'm on windows 10), if CTRL + C (Cancel/Abort) Command on cli doesn't work, and the screen shows up like this:
Try to hit ENTER first (or any key would do) and then CTRL + C and the current process would ask if you want to terminate the batch job:
Perhaps CTRL+C only terminates the parent process while npm start runs with other child processes. Quite unsure why you have to hit that extra key though prior to CTRL+ C, but it works better than having to close the command line and start again.
A related issue you might want to check: https://github.com/mysticatea/npm-run-all/issues/74
Here's another solution that mixes ideas from the previous answers. It takes the "kill process" approach while addressing the concern about platform independence.
It relies on the tree-kill package to handle killing the server process tree. I found killing the entire process tree necessary in my projects because some tools (e.g. babel-node) spawn child processes. If you only need to kill a single process, you can replace tree-kill with the built-in process.kill() method.
The solution follows (the first two arguments to spawn() should be modified to reflect the specific recipe for running your server):
build/start-server.js
import { spawn } from 'child_process'
import fs from 'fs'
const child = spawn('node', [
'dist/server.js'
], {
detached: true,
stdio: 'ignore'
})
child.unref()
if (typeof child.pid !== 'undefined') {
fs.writeFileSync('.server.pid', child.pid, {
encoding: 'utf8'
})
}
build/stop-server.js
import fs from 'fs'
import kill from 'tree-kill'
const serverPid = fs.readFileSync('.server.pid', {
encoding: 'utf8'
})
fs.unlinkSync('.server.pid')
kill(serverPid)
package.json
"scripts": {
"start": "babel-node build/start-server.js",
"stop": "babel-node build/stop-server.js"
}
Note that this solution detaches the start script from the server (i.e. npm start will return immediately and not block until the server is stopped). If you prefer the traditional blocking behavior, simply remove the options.detached argument to spawn() and the call to child.unref().
In case your json file does not have a script to stop the app, an option that I use is just by pressing ctrl+C on the cmd.
If is very simple, just kill the process..
localmacpro$ ps
PID TTY TIME CMD
5014 ttys000 0:00.05 -bash
6906 ttys000 0:00.29 npm
6907 ttys000 0:06.39 node /Users/roger_macpro/my-project/node_modules/.bin/webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
6706 ttys001 0:00.05 -bash
7157 ttys002 0:00.29 -bash
localmacpro$ kill -9 6907 6906
You can use pm2
https://pm2.keymetrics.io/docs/usage/quick-start/
after installation just type in terminal
pm2 start app.js
and then
pm2 stop 0 to stop your server
All (3) solotion is :
1- ctlr + C
2- in json file
wreite a script that stop
"scripts": {
"stop": "killall -SIGINT this-name-can-be-as-long-as-it-needs-to-be"
},
*than in command write // npm stop //
3- Restart the pc
For production environments you should use Forever.js
It's so util for start and stop node process, you can list apps running too.
https://github.com/foreverjs/forever
You have to press combination ctrl + z
My os is Ubuntu

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