Running Your Node.js App as an Upstart Service

When you are developing a Node.js application, you typically run it like this:

$ node index.js

That's more than enough for debugging purposes, but what happens when you are ready to deploy to your production server?

Obviously, the above method is not adequate, since on your production server you want your application to:

  • Run in the background, even after you terminate your current shell session

  • Log STDOUT to a file

  • Restart automatically in case of crash, or server reboot

There are several methods to achieve these goals, but my favorite is to run the application as an Upstart service. Upstart allows you to run your Node.js application as a daemon, automatically restarts it if required, and provides a set of commands for manually starting / stopping your application.

This tutorial will show you how to create an Upstart script on Ubuntu 14.04. Since we should never run a Node.js application as root on a production server, we start by creating a new user.

  1. Create a new user:

    $ adduser www
  2. Create a directory to save PID files:

    $ mkdir /home/www/run
    $ chown -R www:www /home/www/run && chmod -R 770 /home/www/run
  3. Create your application directory and transfer the source files:

    $ mkdir /home/www/MY_APP
    $ mkdir /home/www/MY_APP/log
    $ chown -R www:www /home/www/MY_APP && chmod -R 770 /home/www/MY_APP
  4. Save the script below at /etc/init/MY_APP.conf:

    description "MY_APP"
    author "MY_NAME"
    env NODE=/usr/bin/nodejs
    env SCRIPT=/home/www/MY_APP/index.js
    env LOG_FILE=/home/www/MY_APP/log/stdout.log
    env PID_FILE=/home/www/run/
    env USER=www
    start on filesystem or runlevel [2345]
    stop on shutdown
    respawn limit 10 5
        exec start-stop-daemon --start --chuid $USER --make-pidfile --pidfile $PID_FILE --exec $NODE $SCRIPT >> $LOG_FILE 2>&1
    end script
    pre-start script
        touch $LOG_FILE
        chown root:$USER $LOG_FILE
        chmod 770 $LOG_FILE
        echo "[`date`] MY_APP starting" >> $LOG_FILE
    end script
    pre-stop script
        rm -f $PID_FILE
        echo "[`date`] MY_APP stopping" >> $LOG_FILE
    end script
  5. Check if your script is valid:

    $ init-checkconf /etc/init/MY_APP.conf

That's it! Now you can start your application with service MY_APP start. Upstart will automatically restart it in case of crash, or server reboot.

If you want to learn more about Upstart, you can have a look at the official documentation here.