Skip to content

Instantly share code, notes, and snippets.

@behrad
Last active December 25, 2015 10:09
Show Gist options
  • Save behrad/6959182 to your computer and use it in GitHub Desktop.
Save behrad/6959182 to your computer and use it in GitHub Desktop.
Node.js Apps as Service in Linux
#!/bin/bash
#
# Service script for a Node.js application running under Forever.
#
# This is suitable for Fedora, Red Hat, CentOS and similar distributions.
# It will not work on Ubuntu or other Debian-style distributions!
#
# There is some perhaps unnecessary complexity going on in the relationship between
# Forever and the server process. See: https://github.com/indexzero/forever
#
# 1) Forever starts its own watchdog process, and keeps its own configuration data
# in /var/run/forever.
#
# 2) If the process dies, Forever will restart it: if it fails but continues to run,
# it won't be restarted.
#
# 3) If the process is stopped via this script, the pidfile is left in place; this
# helps when issues happen with failed stop attempts.
#
# 4) Which means the check for running/not running is complex, and involves parsing
# of the Forever list output.
#
# chkconfig: 345 80 20
# description: my application description
# processname: my_application_name
# pidfile: /var/run/my_application_name.pid
# logfile: /var/log/my_application_name.log
#
# Source function library.
. /etc/init.d/functions
NAME=my_application_name
SOURCE_DIR=/path/to/my/application/package/scripts
SOURCE_FILE=start.js
user=node
pidfile=/var/run/$NAME.pid
logfile=/var/log/$NAME.log
forever_dir=/var/run/forever
node=node
forever=forever
sed=sed
export PATH=$PATH:/home/node/local/node/bin
export NODE_PATH=$NODE_PATH:/home/node/local/node/lib/node_modules
start() {
echo "Starting $NAME node instance: "
if [ "$foreverid" == "" ]; then
# Create the log and pid files, making sure that
# the target use has access to them
touch $logfile
chown $user $logfile
touch $pidfile
chown $user $pidfile
# Launch the application
daemon --user=root \
$forever start -p $forever_dir --pidFile $pidfile -l $logfile \
-a -d $SOURCE_DIR/$SOURCE_FILE
RETVAL=$?
else
echo "Instance already running"
RETVAL=0
fi
}
stop() {
echo -n "Shutting down $NAME node instance : "
if [ "$foreverid" != "" ]; then
$node $SOURCE_DIR/prepareForStop.js
$forever stop -p $forever_dir $id
else
echo "Instance is not running";
fi
RETVAL=$?
}
if [ -f $pidfile ]; then
read pid < $pidfile
else
pid=""
fi
if [ "$pid" != "" ]; then
# Gnarly sed usage to obtain the foreverid.
sed1="/$pid\]/p"
sed2="s/.*\[\([0-9]\+\)\].*\s$pid\.*/\1/g"
foreverid=`$forever list -p $forever_dir | $sed -n $sed1 | $sed $sed2`
else
foreverid=""
fi
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status -p ${pidfile}
;;
*)
echo "Usage: {start|stop|status}"
exit 1
;;
esac
exit $RETVAL
#!/bin/bash
#
# An example init script for running a Node.js process as a service
# using Forever as the process monitor. For more configuration options
# associated with Forever, see: https://github.com/nodejitsu/forever
#
# You will need to set the environment variables noted below to conform to
# your use case, and change the init info comment block.
#
# This was written for Debian distributions such as Ubuntu, but should still
# work on RedHat, Fedora, or other RPM-based distributions, since none
# of the built-in service functions are used. If you do adapt it to a RPM-based
# system, you'll need to replace the init info comment block with a chkconfig
# comment block.
#
### BEGIN INIT INFO
# Provides: my-application
# Required-Start: $syslog $remote_fs
# Required-Stop: $syslog $remote_fs
# Should-Start: $local_fs
# Should-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: My Application
# Description: My Application
### END INIT INFO
#
# Based on:
# https://gist.github.com/3748766
# https://github.com/hectorcorrea/hectorcorrea.com/blob/master/etc/forever-initd-hectorcorrea.sh
# https://www.exratione.com/2011/07/running-a-nodejs-server-as-a-service-using-forever/
# Source function library. Note that this isn't used here, but remains to be
# uncommented by those who want to edit this script to add more functionality.
# Note that this is Ubuntu-specific. The scripts and script location are different on
# RPM-based distributions.
# . /lib/lsb/init-functions
# The example environment variables below assume that Node.js is
# installed into /home/node/local/node by building from source as outlined
# here:
# https://www.exratione.com/2011/07/running-a-nodejs-server-as-a-service-using-forever/
#
# It should be easy enough to adapt to the paths to be appropriate to a
# package installation, but note that the packages available for Ubuntu in
# the default repositories are far behind the times. Most users will be
# building from source to get a more recent Node.js version.
#
# An application name to display in echo text.
# NAME="My Application"
# The full path to the directory containing the node and forever binaries.
# NODE_BIN_DIR=/home/node/local/node/bin
# Set the NODE_PATH to the Node.js main node_modules directory.
# NODE_PATH=/home/node/local/node/lib/node_modules
# The directory containing the application start Javascript file.
# APPLICATION_DIRECTORY=/home/node/my-application
# The application start Javascript filename.
# APPLICATION_START=start-my-application.js
# Process ID file path.
# PIDFILE=/var/run/my-application.pid
# Log file path.
# LOGFILE=/var/log/my-application.log
#
NAME="Opxi2 Core Messaging Queue"
NODE_BIN_DIR=
NODE_PATH=
#APPLICATION_DIRECTORY=/opt/opxi2/node_modules/opxi2node/bin
APPLICATION_DIRECTORY=/data/workspace/opxi2-nodejs/bin
APPLICATION_START=kue-console
PIDFILE=$APPLICATION_START.pid
LOGFILE=/var/log/opxi2/$APPLICATION_START.log
FOREVER_PID_DIR=/home/jrad/.forever/pids/
# Add node to the path for situations in which the environment is passed.
PATH=$NODE_BIN_DIR:$PATH
# Export all environment variables that must be visible for the Node.js
# application process forked by Forever. It will not see any of the other
# variables defined in this script.
export NODE_PATH=$NODE_PATH
start() {
if [ -f $FOREVER_PID_DIR/$PIDFILE ]; then
echo "$NAME already running"
RETVAL=0
else
echo "Starting $NAME"
# The minUptime and spinSleepTime settings stop Forever from thrashing if
# the application fails immediately on launch. This is generally necessary to
# avoid loading development servers to the point of failure every time
# someone makes an error in application initialization code, or bringing down
# production servers the same way if a database or other critical service
# suddenly becomes inaccessible.
#
# The pidfile contains the child process pid, not the forever process pid.
# We're only using it as a marker for whether or not the process is
# running.
forever --minUptime 5000 --spinSleepTime 2000 -m 1000 -a -l $LOGFILE \
--pidFile $FOREVER_PID_DIR/$PIDFILE --sourceDir $APPLICATION_DIRECTORY \
start $APPLICATION_START.js 2>&1 >/dev/null
forever list | grep $APPLICATION_START
RETVAL=$?
fi
}
stop() {
if [ -f $FOREVER_PID_DIR/$PIDFILE ]; then
echo "Shutting down $NAME"
forever stop $APPLICATION_START.js
# Get rid of the pidfile, since Forever won't do that.
rm -f $FOREVER_PID_DIR/$PIDFILE
RETVAL=$?
else
echo "$NAME is not running"
RETVAL=0
fi
}
restart() {
echo "Restarting $NAME"
# stop
# start
kill `cat $FOREVER_PID_DIR/$PIDFILE`
}
status() {
echo "Status for $NAME:"
forever list | grep $APPLICATION_START
RETVAL=$?
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
restart
;;
*)
echo "Usage: {start|stop|status|restart}"
exit 1
;;
esac
exit $RETVAL
@behrad
Copy link
Author

behrad commented Oct 13, 2013

/sbin/chkconfig --level 345 my_application_name on

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment