Upstart and Node.js

Upstart and Node.js

One issue that we have had with Node.js projects is how to allow our developers to assume the role of devops for the various different sites a machine may be running - i.e. to restart node sites without incurring a large overhead in server configuration.

To date we have been running our node sites out of the Upstart system in Ubuntu Linux, and are using one upstart script per site.  With a server running several sites, this would translate to a lot of these scripts, all pretty much identical apart from some variables.

My solution to this is as follows....

First of all, there are a few dependencies to mention.

  • The first is that we are dependent on Upstart.  Other than Ubuntu, there are a few recent distributions that also use the system.  Redhat Enterprise 6 and Fedora 6 are listed as supporting it on the wikipedia page for Upstart.
  • The next is of course Node.js.  This method could however be transferable to other services that run lots of individual instances.
  • Lastly, we need a way of maintaining the right version of node for each instance, and we use n (npm install -g n) for this purpose.

The solution comes in two parts.  One upstart script to start each node instance, the second to start them all on boot.

 

Part One: node.conf

description 'node upstart script'
author 'iain'

start on (local-filesystems and net-device-up)
stop on shutdown

instance "Node - $NAME"

respawn
respawn limit 5 60

script
        . /etc/node/$NAME.conf
        exec sudo -u node NODE_ENV=${NODE_ENV} /usr/bin/n use ${NODE_VERSION} ${NODE_PATH} >> ${LOG_PATH} 2>&1
end script
The key to running multiple instances is in the 'instance' keyword above, and we pass in the NAME variable on the command line to specify which instance we are operating on. Another thing that you'll notice is that we are sourcing a configuration file, this is so that we can populate the rest of the script with variables, so the next step is to create this directory and set the variables for one application. For my test node app, I've very creatively called it test, and have decided it's running in a production environment.  Therefore my config file is /etc/node/test-production.conf and contains:
NODE_VERSION="0.6.5"
NODE_PATH="/var/application/test/app.js"
LOG_PATH="/var/log/node/test.log"
NODE_ENV="production"
Starting this node instance is easy, we run:
# start node NAME=test-production
And as output we get:
# start node NAME=test-production
node (Node - test-production) start/running, process 1562
All is good, we can stop/start/restart/respawn this service, but it won't start automagically on boot.  For this we need....   Part Two: nodeSites.conf
description 'Start all node instances at boot'
author 'iain'

start on (local-filesystems and net-device-up)

task

script
  for file in `ls /etc/node/*.conf` ; do
    filename=`basename ${file%.*}`
    start node NAME=$filename
  done
end script

As you can see, this script will cycle through all config files in /etc/node and start a node instance for each based on the name of the file (minus path and extension for those unfamiliar with the `basename ${file%.*}` line).

The key thing to mention about this script is the task keyword.  It is this that makes this upstart script a short lived process - it does its thing then dies off.

 

More information on the technologies mentioned can be found at....

NodeJS - http://nodejs.org

NPM module n by TJ Holowaychuk - http://github.com/visionmedia/n

Upstart Cookbook - http://upstart.ubuntu.com/cookbook

Ubuntu - http://ubuntu.com

Bash Manual - http://www.gnu.org/software/bash/manual/bashref.html

 

Want to discuss a project?

Got a question? Want some more detail? We'd love to hear from you, contact Jason on +44 (0)1923 261166 or jason.treloar@clock.co.uk.

Related

Blog-post-img-01.jpgRead
Article
26 April 2016

MongoDB Performance on ZFS and Linux

Here at Clock we love ZFS, and have been running it in production on our Linux file servers for several years. It provides us with numerous excellent features. With the recent release of Ubuntu Xenial 16.04 official support for ZFS is now here, and we are keen to integrate it fully into our next generation hosting stack.

node blog post.jpgRead
Article
9 March 2016

A Simple Website in Node.js – 2016 Edition

Four years ago I wrote a post on how to build a simple website in Node.js. Seeing as it’s still the most popular article on this blog, I thought I’d take a look at how things have evolved, what I would do differently today, and some additional nuggets of advice.

legoblog.jpgRead
Article
24 February 2016

JavaScript Frameworks in 2016

As JavaScript's popularity continues to grow and with it, the surrounding ecosystem of modern libraries & tools, it can sometimes be hard to keep-up, leading to what some describe as JavaScript Fatigue. This post will delve into some of the advances we're seeing in the JavaScript community and how such solutions may benefit you and your team, without making you fatigued.

Blog-image-16x9.jpgRead
Article
22 October 2015

Moving from Mac to Linux

Shortly before I moved house about a month ago, unsatisfied with the impending chaos, my hand (without first consulting my head) decided to launch a full pint of squash at my MacBook Air. I swiftly unplugged the power cable and took it to my neighbourhood Mac engineer. It was already too late – it was pronounced dead on arrival.

Come and work for Clock

Clock is made up of bright, hard-working and talented people and we're always on the look out for more. You can browse the current jobs below or follow us @clock for the latest vacancies.

View Latest
Vacancies