How to use Ubuntu's Upstart to Control Node.js Forever
Recently I needed to start a server written in Node.js. This server was deployed on Ubuntu 12.04, and I wanted it to be started using the system's init system. Yet I also wanted the safety of Forever, a script manager for Node.js.
Ubuntu still supports the classic SysV init style, but it also now supports the far more sophisticated Upstart system. It is appealing for a few reasons: One is that it feels simpler and cleaner. Another is that it is more powerful and easily more configurable. I decided to use it for my scripts.
This article explains how to use Upstart, Forever, and Node.js together to run a Node.js server as a daemon process that is automatically started at system startup, and automatically stops at shutdown or reboot. <!--break-->
An Upstart File
The first thing to do is create an Upstart configuration file. I keep mine in my source code along with the app, and copy it into
/etc/init when I install onto the server.
# node-example.conf description "Example of starting Node with Upstart and Forever" # Start up when the system hits any normal runlevel, and # shuts down when the system goes to shutdown or reboot. start on filesystem or runlevel  stop on runlevel  # IMPORTANT: You will want to use this with Forever. It # tells Upstart that forever is going to fork after it # starts. expect fork # This monitors Forever, which seems gratuitous. # TIP: Comment these out while debugging your script. respawn respawn limit 5 30 # Send error messages to the console. Useful for debugging. console output # exampleuser is a very low-privileged user. We run as # this user instead of as root (the default user). setuid exampleuser # The user's home directory env HOME=/home/exampleuser # Now we run Forever, telling it to write its logs to # /tmp, and to run the script /opt/example/server.js script cd $HOME exec forever start -a -l /tmp/forever.log -o /tmp/forever.stdout.log -e /tmp/forever.stderr.log /opt/example/server.js end script
Upstart has quite a few configuration options. The above is minimal, but if you have more sophisticated needs, you might want to check out the (well written) manual for Upstart.
Starting and Stopping
Once you have a configuration file like the one above, you can drop it in
/etc/init and then test it using the
My configuration file is
node-example.conf, so to start it, I issue this command:
$ sudo start node-example
Just because it looks like it started okay doesn't necessarily mean that it did. You can use
ps -ef to see if your
node processes are running. Even more telling, though, is the output of this command:
$ sudo initctl list
Output should look something like this:
mountall-net stop/waiting passwd stop/waiting rc stop/waiting rsyslog start/running, process 708 screen-cleanup stop/waiting tty4 start/running, process 738 udev start/running, process 299 upstart-udev-bridge start/running, process 293 ureadahead-other stop/waiting
That will list all of the start/stop scripts and tell you the status of each.
node-example should be in that list, and should be listed as
start/running with a PID. If it is listed as
stop/waiting, then either the Forever process died or your
expect setting (in the config file) is not correct.
As I debugged my script, I found the most difficult part had to do with permissions for my
setuid user. It's important that the user be able to write to the
$HOME directory, since that is where Forever stores its