[node.js] How do I run a node.js app as a background service?

Since this post has gotten a lot of attention over the years, I've listed the top solutions per platform at the bottom of this post.


Original post:

I want my node.js server to run in the background, i.e.: when I close my terminal I want my server to keep running. I've googled this and came up with this tutorial, however it doesn't work as intended. So instead of using that daemon script, I thought I just used the output redirection (the 2>&1 >> file part), but this too does not exit - I get a blank line in my terminal, like it's waiting for output/errors.

I've also tried to put the process in the background, but as soon as I close my terminal the process is killed as well.

So how can I leave it running when I shut down my local computer?


Top solutions:

This question is related to node.js process background server daemon

The answer is


Node.js as a background service in WINDOWS XP

Installation:

  1. Install WGET http://gnuwin32.sourceforge.net/packages/wget.htm via installer executable
  2. Install GIT http://code.google.com/p/msysgit/downloads/list via installer executable
  3. Install NSSM http://nssm.cc/download/?page=download via copying nnsm.exe into %windir%/system32 folder
  4. Create c:\node\helloworld.js

    // http://howtonode.org/hello-node
    var http = require('http');
    var server = http.createServer(function (request, response) {
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.end("Hello World\n");
    });
    server.listen(8000);
    console.log("Server running at http://127.0.0.1:8000/");
    
  5. Open command console and type the following (setx only if Resource Kit is installed)

    C:\node> set path=%PATH%;%CD%
    C:\node> setx path "%PATH%"
    C:\node> set NODE_PATH="C:\Program Files\nodejs\node_modules"
    C:\node> git config --system http.sslcainfo /bin/curl-ca-bundle.crt    
    C:\node> git clone --recursive git://github.com/isaacs/npm.git    
    C:\node> cd npm    
    C:\node\npm> node cli.js install npm -gf   
    C:\node> cd ..    
    C:\node> nssm.exe install node-helloworld "C:\Program Files\nodejs\node.exe" c:\node\helloworld.js    
    C:\node> net start node-helloworld
    
  6. A nifty batch goodie is to create c:\node\ServiceMe.cmd

    @echo off
    nssm.exe install node-%~n1 "C:\Program Files\nodejs\node.exe" %~s1
    net start node-%~n1
    pause
    

Service Management:

  • The services themselves are now accessible via Start-> Run-> services.msc or via Start->Run-> MSCONFIG-> Services (and check 'Hide All Microsoft Services').
  • The script will prefix every node made via the batch script with 'node-'.
  • Likewise they can be found in the registry: "HKLM\SYSTEM\CurrentControlSet\Services\node-xxxx"

If you are running nodejs in linux server, I think this is the best way.

Create a service script and copy to /etc/init/nodejs.conf

start service: sudo service nodejs start

stop service: sudo service nodejs stop

Sevice script

description "DManager node.js server - Last Update: 2012-08-06"
author      "Pedro Muniz - [email protected]"

env USER="nodejs" #you have to create this user 
env APPNAME="nodejs" #you can change the service name
env WORKDIR="/home/<project-home-dir>" #set your project home folder here
env COMMAND="/usr/bin/node <server name>" #app.js ?

# used to be: start on startup
# until we found some mounts weren't ready yet while booting:
start on started mountall
stop on shutdown

# Automatically Respawn:
respawn
respawn limit 99 5

pre-start script
    sudo -u $USER echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" >> /var/log/$APPNAME.log
end script

script
    # Not sure why $HOME is needed, but we found that it is:
    export HOME="<project-home-dir>"  #set your project home folder here
    export NODE_PATH="<project node_path>"

    #log file, grant permission to nodejs user
    exec start-stop-daemon --start --make-pidfile --pidfile /var/run/$APPNAME.pid --chuid $USER --chdir $WORKDIR --exec $COMMAND >> /var/log/$APPNAME.log 2>&1
end script

post-start script
   # Optionally put a script here that will notifiy you node has (re)started
   # /root/bin/hoptoad.sh "node.js has started!"
end script

pre-stop script
    sudo -u $USER echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/$APPNAME.log
end script

use nssm the best solution for windows, just download nssm, open cmd to nssm directory and type

nssm install <service name> <node path> <app.js path> 

eg: nssm install myservice "C:\Program Files\nodejs" "C:\myapp\app.js" 

this will install a new windows service which will be listed at services.msc from there you can start or stop the service, this service will auto start and you can configure to restart if it fails.


The accepted answer is probably the best production answer, but for a quick hack doing dev work, I found this:

nodejs scriptname.js & didn't work, because nodejs seemed to gobble up the &, and so the thing didn't let me keep using the terminal without scriptname.js dying.

But I put nodejs scriptname.js in a .sh file, and nohup sh startscriptname.sh & worked.

Definitely not a production thing, but it solves the "I need to keep using my terminal and don't want to start 5 different terminals" problem.


I am surprised that nobody has mentioned Guvnor

I have tried forever, pm2, etc. But, when it comes to solid control and web based performance metrics, I have found Guvnor to be by far the best. Plus, it is also fully opensource.

enter image description here

Edit : However, I am not sure if it works on windows. I've only used it on linux.


I use Supervisor for development. It just works. When ever you make changes to a .js file Supervisor automatically restarts your app with those changes loaded.

Here's a link to its Github page

Install :

sudo npm install supervisor -g

You can easily make it watch other extensions with -e. Another command I use often is -i to ignore certain folders.

You can use nohup and supervisor to make your node app run in the background even after you log out.

sudo nohup supervisor myapp.js &


This might not be the accepted way, but I do it with screen, especially while in development because I can bring it back up and fool with it if necessary.

screen
node myserver.js
>>CTRL-A then hit D

The screen will detach and survive you logging off. Then you can get it back back doing screen -r. Hit up the screen manual for more details. You can name the screens and whatnot if you like.


June 2017 Update:
Solution for Linux: (Red hat). Previous comments doesn't work for me. This works for me on Amazon Web Service - Red Hat 7. Hope this works for somebody out there.

A. Create the service file 
sudo vi /etc/systemd/system/myapp.service
[Unit]
Description=Your app
After=network.target

[Service]
ExecStart=/home/ec2-user/meantodos/start.sh
WorkingDirectory=/home/ec2-user/meantodos/

[Install]
WantedBy=multi-user.target

B. Create a shell file
/home/ec2-root/meantodos/start.sh
#!/bin/sh -
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 8080
npm start

then:
chmod +rx /home/ec2-root/meantodos/start.sh
(to make this file executable)

C. Execute the Following

sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl status myapp

(If there are no errors, execute below.  Autorun after server restarted.)
chkconfig myapp -add

This answer is quite late to the party, but I found that the best solution was to write a shell script that used the both the screen -dmS and nohup commands.

screen -dmS newScreenName nohup node myserver.js >> logfile.log

I also add the >> logfile bit on the end so I can easily save the node console.log() statements.

Why did I use a shell script? Well I also added in an if statement that checked to see if the node myserver.js process was already running.

That way I was able to create a single command line option that both lets me keep the server going and also restart it when I have made changes, which is very helpful for development.


For people using newer versions of the daemon npm module - you need to pass file descriptors instead of strings:

var fs = require('fs');
var stdoutFd = fs.openSync('output.log', 'a');
var stderrFd = fs.openSync('errors.log', 'a');
require('daemon')({
    stdout: stdoutFd, 
    stderr: stderrFd
});

If you are running OSX, then the easiest way to produce a true system process is to use launchd to launch it.

Build a plist like this, and put it into the /Library/LaunchDaemons with the name top-level-domain.your-domain.application.plist (you need to be root when placing it):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>top-level-domain.your-domain.application</string>

    <key>WorkingDirectory</key>
    <string>/your/preferred/workingdirectory</string>

    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/node</string>
        <string>your-script-file</string>
    </array>

    <key>RunAtLoad</key>
    <true/>

    <key>KeepAlive</key>
    <true/>

</dict>
</plist>

When done, issue this (as root):

launchctl load /Library/LaunchDaemons/top-level-domain.your-domain.application.plist
launchctl start top-level-domain.your-domain.application

and you are running.

And you will still be running after a restart.

For other options in the plist look at the man page here: https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man5/launchd.plist.5.html


has anyone noticed a trivial mistaken of the position of "2>&1" ?

2>&1 >> file

should be

>> file 2>&1

Try to run this command if you are using nohup -

nohup npm start 2>/dev/null 1>/dev/null&

You can also use forever to start server

forever start -c "npm start" ./ 

PM2 also supports npm start

pm2 start npm -- start

UPDATE - As mentioned in one of the answers below, PM2 has some really nice functionality missing from forever. Consider using it.

Original Answer

Use nohup:

nohup node server.js &

EDIT I wanted to add that the accepted answer is really the way to go. I'm using forever on instances that need to stay up. I like to do npm install -g forever so it's in the node path and then just do forever start server.js


To round out the various options suggested, here is one more: the daemon command in GNU/Linux, which you can read about here: http://libslack.org/daemon/manpages/daemon.1.html. (apologies if this is already mentioned in one of the comments above).


I use tmux for a multiple window/pane development environment on remote hosts. It's really simple to detach and keep the process running in the background. Have a look at tmux


Check out fugue! Apart from launching many workers, you can demonize your node process too!

http://github.com/pgte/fugue


PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks. https://github.com/Unitech/pm2


You can use Forever, A simple CLI tool for ensuring that a given node script runs continuously (i.e. forever): https://www.npmjs.org/package/forever


If you simply want to run the script uninterrupted until it completes you can use nohup as already mentioned in the answers here. However, none of the answers provide a full command that also logs stdin and stdout.

nohup node index.js >> app.log 2>&1 &
  • The >> means append to app.log.
  • 2>&1 makes sure that errors are also send to stdout and added to the app.log.
  • The ending & makes sure your current terminal is disconnected from command so you can continue working.

If you want to run a node server (or something that should start back up when the server restarts) you should use systemd / systemctl.


If you are using pm2, you can use it with autorestart set to false:

$ pm2 ecosystem

This will generate a sample ecosystem.config.js:

module.exports = {
  apps: [
    {
      script: './scripts/companies.js',
      autorestart: false,
    },
    {
      script: './scripts/domains.js',
      autorestart: false,
    },
    {
      script: './scripts/technologies.js',
      autorestart: false,
    },
  ],
}

$ pm2 start ecosystem.config.js


Since I'm missing this option in the list of provided answers I'd like to add an eligible option as of 2020: docker or any equivalent container platform. In addition to ensuring your application is working in a stable environment there are additional security benefits as well as improved portability.

There is docker support for Windows, macOS and most/major Linux distributions. Installing docker on a supported platform is rather straight-forward and well-documented. Setting up a Node.js application is as simple as putting it in a container and running that container while making sure its being restarted after shutdown.

Create Container Image

Assuming your application is available in /home/me/my-app on that server, create a text file Dockerfile in folder /home/me/my-app with content similar to this one:

FROM node:lts-alpine
COPY /my-app /app
CMD ["/app/server.js"]

Create the image using command like this:

docker build -t myapp-as-a-service /home/me

Note: Last parameter is selecting folder containing that Dockerfile instead of the Dockerfile itself. You may pick a different one using option -f.

Start Container

Use this command for starting the container:

docker run -d --restart always -p 80:3000 myapp-as-a-service

This command is assuming your app is listening on port 3000 and you want it to be exposed on port 80 of your host.

This is a very limited example for sure, but it's a good starting point.


I am simply using the daemon npm module:

var daemon = require('daemon');

daemon.daemonize({
    stdout: './log.log'
  , stderr: './log.error.log'
  }
, './node.pid'
, function (err, pid) {
  if (err) {
    console.log('Error starting daemon: \n', err);
    return process.exit(-1);
  }
  console.log('Daemonized successfully with pid: ' + pid);

  // Your Application Code goes here
});

Lately I'm also using mon(1) from TJ Holowaychuk to start and manage simple node apps.


UPDATE: i updated to include the latest from pm2:

for many use cases, using a systemd service is the simplest and most appropriate way to manage a node process. for those that are running numerous node processes or independently-running node microservices in a single environment, pm2 is a more full featured tool.

https://github.com/unitech/pm2

http://pm2.io

  • it has a really useful monitoring feature -> pretty 'gui' for command line monitoring of multiple processes with pm2 monit or process list with pm2 list
  • organized Log management -> pm2 logs
  • other stuff:
    • Behavior configuration
    • Source map support
    • PaaS Compatible
    • Watch & Reload
    • Module System
    • Max memory reload
    • Cluster Mode
    • Hot reload
    • Development workflow
    • Startup Scripts
    • Auto completion
    • Deployment workflow
    • Keymetrics monitoring
    • API

2016 Update: The node-windows/mac/linux series uses a common API across all operating systems, so it is absolutely a relevant solution. However; node-linux generates systemv init files. As systemd continues to grow in popularity, it is realistically a better option on Linux. PR's welcome if anyone wants to add systemd support to node-linux :-)

Original Thread:

This is a pretty old thread now, but node-windows provides another way to create background services on Windows. It is loosely based on the nssm concept of using an exe wrapper around your node script. However; it uses winsw.exe instead and provides a configurable node wrapper for more granular control over how the process starts/stops on failures. These processes are available like any other service:

enter image description here

The module also bakes in some event logging:

enter image description here

Daemonizing your script is accomplished through code. For example:

var Service = require('node-windows').Service;

// Create a new service object
var svc = new Service({
  name:'Hello World',
  description: 'The nodejs.org example web server.',
  script: 'C:\\path\\to\\my\\node\\script.js'
});

// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on('install',function(){
  svc.start();
});

// Listen for the "start" event and let us know when the
// process has actually started working.
svc.on('start',function(){
  console.log(svc.name+' started!\nVisit http://127.0.0.1:3000 to see it in action.');
});

// Install the script as a service.
svc.install();

The module supports things like capping restarts (so bad scripts don't hose your server) and growing time intervals between restarts.

Since node-windows services run like any other, it is possible to manage/monitor the service with whatever software you already use.

Finally, there are no make dependencies. In other words, a straightforward npm install -g node-windows will work. You don't need Visual Studio, .NET, or node-gyp magic to install this. Also, it's MIT and BSD licensed.

In full disclosure, I'm the author of this module. It was designed to relieve the exact pain the OP experienced, but with tighter integration into the functionality the Operating System already provides. I hope future viewers with this same question find it useful.


Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to process

Fork() function in C How to kill a nodejs process in Linux? Xcode process launch failed: Security Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes Linux Script to check if process is running and act on the result CreateProcess error=2, The system cannot find the file specified How to make parent wait for all child processes to finish? How to use [DllImport("")] in C#? Visual Studio "Could not copy" .... during build How to terminate process from Python using pid?

Examples related to background

SwiftUI - How do I change the background color of a View? Changing background color of selected item in recyclerview Android Studio Image Asset Launcher Icon Background Color Android: keep Service running when app is killed How to set a background image in Xcode using swift? CSS Background image not loading css transition opacity fade background how to set the background image fit to browser using html background:none vs background:transparent what is the difference? How to scale images to screen size in Pygame

Examples related to server

npm WARN enoent ENOENT: no such file or directory, open 'C:\Users\Nuwanst\package.json' Golang read request body currently unable to handle this request HTTP ERROR 500 How do I solve the "server DNS address could not be found" error on Windows 10? Server http:/localhost:8080 requires a user name and a password. The server says: XDB What does "app.run(host='0.0.0.0') " mean in Flask How to configure port for a Spring Boot application Apache2: 'AH01630: client denied by server configuration' Apache is not running from XAMPP Control Panel ( Error: Apache shutdown unexpectedly. This may be due to a blocked port) Express.js - app.listen vs server.listen

Examples related to daemon

How to stop docker under Linux Docker command can't connect to Docker daemon What does the DOCKER_HOST variable do? Android Studio Gradle project "Unable to start the daemon process /initialization of VM" Android Studio: Unable to start the daemon process How to process SIGTERM signal gracefully? Creating a daemon in Linux Getting pids from ps -ef |grep keyword How do I run a node.js app as a background service? Best way to make a shell script daemon?