Deploying a Node.js application as a service

I have confirmed that this process works on:

  • CentOS
  • Amazon Linux

On the instance make sure that you have node and npm - you can get them from the EPEL repo:

yum install -y gcc-c++ make nodejs npm –enablerepo=epel

The npm module forever is useful for running extended processes:

npm install -g forever

Start your node application:

forever start -a /node/$PROG/app.js

And to stop the running application:

forever stop /node/$PROG/app.js

Creating an init script for Node.js

Here’s a basic init script for Node.js using forever as in the example above (assuming the application is in /node/$PROG):

/etc/init.d/appname:

#!/bin/bash
#
# chkconfig: 345 20 50
# description: An example init script for nodejs.
# processname: nodejs-app
#
# Source function library.
. /etc/init.d/functions


RETVAL=0
PROG="nodejs-app"
LOCKFILE=/var/lock/subsys/$PROG


start() {
        echo -n "Starting $PROG: \\n\\r"
        forever start -a -l /var/log/$PROG.log -o /var/log/$PROG-out.log -e /var/log/$PROG-err.log /node/$PROG/app.js
        RETVAL=$?
        \[ $RETVAL -eq 0 \] && touch $LOCKFILE
        echo
        return $RETVAL
}

stop() {
        echo -n "Shutting down $PROG: \\n\\r"
        forever stop /node/$PROG/app.js
        RETVAL=$?
        \[ $RETVAL -eq 0 \] && rm -f $LOCKFILE
        echo
        return $RETVAL
}

status() {
        echo -n "Checking $PROG status: \\n\\r"
        forever list | grep /node/$PROG
        RETVAL=$?
        return $RETVAL
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        stop
        start
        ;;
    \*)
        echo "Usage: $PROG {start|stop|status|restart}"
        exit 1
        ;;
esac
exit $RETVAL

Bonus Points! Use SaltStack to deploy a Node.js application

For readers of my previous post on SaltStack, here’s a quick example state for deploying a Node.js application:

/srv/salt/appname/init.sls:

appname-prereqs:
  pkg.installed:
    - names:
      - gcc
      - gcc-c++
      - make
      - nodejs
      - npm
  npm.installed:
    - name: forever
    - require:
      - pkg: npm

appname:
  npm.bootstrap:
    - name: /node/appname
    - require:
      - pkg: npm
  service:
    - running
    - name: appname
    - enable: True
    - require:
      - pkg: nodejs
      - pkg: npm
    - watch:
      - file: /node/appname/app/config.js
  grains.present:
    - name: appname
    - value: version
  file.recurse:
    - name: /node/appname
    - source: salt://appname/files

Alternatively if you want to sync from a GitHub account (or similar git service):

gitlab.example.com:
  ssh\_known\_hosts:
    - present
    - user: root
    - enc: ecdsa
    - fingerprint: 4e:94:b0:54:c1:5b:29:a2:70:0e:e1:a3:51:ee:ee:e3

appname:
  git.latest:
    - name: git@gitlab.example.com:user/website.git
    - rev: master
    - target: /node/appname
    - identity: /root/.ssh/website\_id\_rsa
    - require:
        - pkg: git
        - ssh\_known\_hosts: gitlab.example.com