Nodejitsu

Save time managing and deploying your node.js app. Code faster with jitsu and npm

Keep a node.js server up with Forever

About the author

Name
Location
Worldwide
nodejitsu nodejitsu

The nodejitsu Platform-as-a-Service is running applications on forever. If you'd like to test the power of forever, without setting up your own server, why don't you try our service?

Our service can be tested free for 2 months, sign up now.

One of the great benefits of using node.js is the reduction in dependencies needed to run a production web application. By using the 'http' module we can run a stand-alone web server in node.js without the need for a separate server like Apache or nginx. The caveat of not having to use these servers is that their concerns are now the concerns of the node.js application developer. The concern that we will discuss in this article is that of fault tolerance, or how to automatically restart your server when it crashes or enters an invalid state.

Before we dive into how to use Forever, lets setup the 'hello world' web server that we will later run with Forever.

var util = require('util'),  
    http = require('http');

http.createServer(function (req, res) {  
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write('hello, i know nodejitsu.')
  res.end();
}).listen(8000);

/* server started */  
util.puts('> hello world running on port 8000');  

The above code starts a web server that will respond to all requests with 'hello, i know nodejitsu'. Starting this server is easy:

$ node simple-server.js
> hello world running on port 8000

Running in the background

By simply running our server script with the 'node' command the server will start as a long running process (i.e. it will block the current shell until it crashes or is forced to exit with Ctrl-C). But what if we want to run this server in the background? The traditional approach is to run the command using nohup:

$ nohup node simple-server.js > output.log &
[1] 23909

This will start our server process in the background and append all output to 'output.log'. Another approach is to start the script as a daemon using a library like daemon.node. I won't go into the details of using daemon.node, but the documentation on the Github project page. These two approaches solve the background problem, but what if we have a buggy server like the one below:

var util = require('util'),  
    http = require('http');

http.createServer(function (req, res) {  
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write('hello, i know nodejitsu.')
  res.end();
}).listen(8000);

/* server started */  
util.puts('> hello world running on port 8000');

setTimeout(function () {  
  util.puts('Throwing error now.');
  throw new Error('User generated fault.');
}, 5000);

This is a contrived example that will start a web server, then throw an unhandled exception after five seconds. If we were to run this script, either in the background or a long running process, it will not automatically restart when it crashes.


Keeping it running with Forever

The purpose of Forever is to keep a child process (such as your node.js web server) running continuously and automatically restart it when it exits unexpectedly. It's worth mentioning that there are other tools written to accomplish this task in a more generic way for any program or programming language:


  1. Monit: http://mmonit.com/monit/
  2. Upstart: http://upstart.ubuntu.com/
  3. Daemontools: http://cr.yp.to/daemontools.html
  4. Launchtool: http://people.debian.org/~enrico/launchtool.html



Currently Forever is for running node.js scripts only, but this is something that may be changed in the future. Honestly, it's a one line fix here, but I'm not sure if users want to put 'node' in-front of every command. Forever is used in production at Nodejitsu and we can confirm that since we deployed it on our servers a month ago, we have not needed to touch it at all. Forever exposes its functionality via a command line interface available after installation via npm:

[sudo] npm install forever

The usage options for Forever expose four simple command line tasks: start, stop, stopall, list:

usage: forever [start | stop | stopall | list] [options] SCRIPT [script options]

options:
  start          start SCRIPT as a daemon
  stop           stop the daemon SCRIPT
  stopall        stop all running forever scripts
  list           list all running forever scripts

You can also use Forever as a long running process by omitting the 'start' option. With these tasks available, starting a nodejs script with Forever is simple:

$ forever start simple-server.js
$ forever list
  [0] simple-server.js [ 24597, 24596 ]

The first command starts the 'simple-server.js' script in the background using daemon.node and returns control to the current shell process. The second command lists all processes running with Forever. The IDs after the script name are the process IDs of the target script and the forever daemon watching that script respectively. We can confirm this by looking at the process list ourselves:

$ ps axl | grep node
  501 24596     1   0  31  0  Ss     ??    0:00.03 node /usr/local/bin/forever start simple-server.js
  501 24597 24412   0  31  0  S      ??    0:00.07 node simple-server.js


Stopping and restarting with Forever

To illustrate that Forever will automatically restart a child process that exits, lets kill the process ourselves:

$ kill 24597
$ forever list
  [0] simple-server.js [ 24611, 24596 ]

As you can see the process ID of the target script 'simple-server.js' has changed from 24597 to 24611 indicating that a new process has been started by Forever. So our target script will run continuously, but how do we stop it? Stopping a process with Forever is simple from the command line. We simply need to pass the index for that process show from 'forever list':

$ forever stop 0
Forever stopped process:
  [0] simple-server.js [ 24611, 24596 ]


Additional Forever options

There are some default options and configuration conventions that you should be aware of when using Forever:

  1. Forever keeps track of running processes in *.fvr files that are placed in /tmp/forever/pids
  2. Each Forever process will generate a unique log file placed in /tmp/forever/*.log
  3. Unless otherwise specified, the output of the child process' stdout and stderr will be written to the above log file.

More about these options are available from the Forever usage and documentation on Github. Pull requests, suggestions and bug reports are welcome.


Other popular posts

- Scaling Isomorphic Javascript Code - Keep a node.js server up with Forever - Package.json dependencies done right - npm cheat sheet - 6 Must Have Node.js Modules Try our service
get $20