Upstart script for node.js app

Ivan Bravo Carlos picture Ivan Bravo Carlos · Dec 21, 2012 · Viewed 14k times · Source

I'm having trouble starting an Upstart script.

Here's the script (app.conf in /etc/init/)

description "node.js server"
author      "kvz"

start on startup
stop on shutdown

script
   # We found $HOME is needed. Without it, we ran into problems
   export HOME="/root"

   exec sudo -u /usr/local/bin/node \
                /var/www/vhosts/travelseguro.com/node/app.js \
                2>&1 >> /var/log/node.log
end script

When I run sudo start app, I get:

start: Unknown job: app

How can I make this work?

Answer

Jujhar Singh picture Jujhar Singh · Mar 25, 2013

I was having the same problem running on the latest Amazon (AWS) linux which is Redhat based.

I have my upstart file in /etc/init called node.conf and when I ran sudo start node I would get a similar error to you start: Unknown job: node.

It turns out that the job won't start if there's an error in your .conf file. So I started out by commenting out all the lines and slowly building up to find the error. The error message isn't very clear and makes it look like upstart can't find your conf file.

Tailing your '/var/log/messages' will help you debug as Upstart logs to there (It may be somewhere different on Ubuntu. Mine said init: /etc/init/node-upstart.conf:8: Unknown stanza which helped me get to the bottom of it. In my particular case I was declaring variables incorrectly.

See on AskUbuntu for a similar thread.

Here's my edited working script:

<!-- language: lang-sh -->
#!upstart
# using upstart http://upstart.ubuntu.com/getting-started.html and node forever  https://github.com/nodejitsu/forever/  
# to run server
# redhat has additional sudo restrictions, you must comment out 'Default requiretty' from /etc/sudoers
#startup monitoring script derived from http://stackoverflow.com/questions/11084279/node-js-setup-for-easy-deployment-and-updating

description "node.js server"
author      "jujhar"
env PROGRAM_NAME="node"
env FULL_PATH="/home/httpd/buto-middleman/public"
env FILE_NAME="forever.js"
env NODE_PATH="/usr/local/bin/node"
env USERNAME="springloops"

start on startup
stop on shutdown

script
    export HOME="/root"  
    export NODE_ENV=staging #development/staging/production

    echo $$ > /var/run/$PROGRAM_NAME.pid
    cd $FULL_PATH        
    #exec sudo -u $USERNAME $NODE_PATH $FULL_PATH/$FILE_NAME >> /var/log/$PROGRAM_NAME.sys.log 2>&1
    exec $NODE_PATH $FULL_PATH/$FILE_NAME >> /var/log/$PROGRAM_NAME.sys.log 2>&1
end script

pre-start script
    # Date format same as (new Date()).toISOString() for consistency
    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" >> /var/log/$PROGRAM_NAME.sys.log
end script

pre-stop script
    rm /var/run/$PROGRAM_NAME.pid
    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/$PROGRAM_NAME.sys.log
end script

-- Edit 2013-06-01 --

If you're on Centos or Amazon Linux like me, take a look at this init.d script.

-- Edit 2013-10-14 --

Here's a link to a gist of an init.d script that I actually use in production on Amazon Linux(Redhat Based). I simply keep it in my project under an init.d folder and then symlink to it in the /etc/init.d folder and now it's a daemon/service!

-- Edit 2014-06-05 --

Check out this awesome blog artcile by Jeff Dickey on Node.js in production using systemd which is much cleaner and easier than all the stuff we've been doing here (IMHO). He also uses Ansible to control his cluster (which I love) but you don't have to go that far if you're not ready.