BASH Script to start a node.js socket server as a service

Basically what i want to accomplish, is some sort of script or method for me to start a node.js socket server script, as a service.

This is to make it so that i don't have to physically run 'node server.js' in SSH and have to sit there with it open.

Any help would be appreciated.

Thanks Scott

It sounds like you want a tool like forever. There's a getting started blog post here.

There are also more generic tools like monit and upstart.

I am personally using forever on my side project and it has worked just fine.

This gets complicated quickly. What you are really asking for is how to "daemonize" a process. It's more than simply running it in the background. Ideally you want to be running it in such a way that it doesn't tie down removable filesystems, and you want to be keeping its log output and not having it spitting to your old terminal. You don't want it accidentally killed when your shell exits, etc...

If you are on a Debian-based system like Ubuntu, the /sbin/start-stop-daemon does much of what you want. Writing an Ubuntu Upstart configuration for it was mentioned, and that's an option too. On other distros like Fedora, systemd provides what is generally considered the "gold plated" version of this automatic daemonization service. It can daemonize and manage basically any program that isn't explicitly interactive.

I don't see anything criminal in wanting to use something different except forever. In my project i also avoid using this kind of tools and more rely on system capabilities. Since i also try to avoid running my application as root, i cannot use SystemV nor Upstart.

And here comes mighty shell scripting! I have created few bash scripts that are doing simply tasks, such as process watchdog with ability to start, stop, restart and query status.

Check this code. Feel free to modify it as you will. To use it -- put your command there in COMMAND parameter. And execute ./path_to_script.sh -start. This will create watchdog process, which will start your node process and watch if it dies or not and if yes, it will restart it. It is far not ideal, so if anyone has something to fix, add, remove here, feel free to comment below.

#!/bin/bash

CURRENT_PATH=$(pwd)

LOGFOLDER=$CURRENT_PATH"/logs/"
PIDFOLDER=$CURRENT_PATH"/pid/"

#PID file where the this script process ID is stored
WATCHDOGPIDFILE=$PIDFOLDER"watchdog-admin.pid"
#PID file where the node process ID is stored
NODEPIDFILE=$PIDFOLDER"node-admin.pid"
#Watchdog process error log file
WATCHDOGLOGFILE=$LOGFOLDER"admin-watchdog-error.log"
#Node process error log file
NODELOGFILE=$LOGFOLDER"admin-error.log"
#Command to be executed on daemon start
COMMAND="node ./admin/app.js 1> /dev/null 2>> $NODELOGFILE"

ARG_1=$1

start() {
    if [ -e $NODEPIDFILE ]; then
        PID=$(cat $NODEPIDFILE)
        if [ $(ps -o pid | grep $PID) ]; then
            return;
        else
            touch $NODEPIDFILE
            nohup $COMMAND &
            echo $! > $NODEPIDFILE
        fi
    else
        touch $NODEPIDFILE
        nohup $COMMAND &
        echo $! > $NODEPIDFILE
    fi
}

stop() {
    if [ -e $NODEPIDFILE ]; then
        PID=$(cat $NODEPIDFILE)
        if [ $(ps -o pid | grep $PID) ]; then
            kill -9 $PID
        fi
        rm $NODEPIDFILE
    fi
}

stopdaemon() {
    stop
    rm $WATCHDOGPIDFILE
    exit 0
}

log() {
    echo $1 >> $WATCHDOGLOGFILE
}

keep_alive() {
    if [ -e $NODEPIDFILE ]; then
        PID=$(cat $NODEPIDFILE)
        if [ $(ps -o pid | grep $PID) ]; then
            return;
        else
            log "Jim, he is dead!! Trying ressurection spell..."
            start
        fi
    else
        start
    fi
}

case x${ARG_1} in
    x-start )

        echo "Starting daemon watchdog"
        nohup "$0" -daemon &> /dev/null &

    ;;

    x-daemon )

        if [ -e $WATCHDOGPIDFILE ]; then
            PID=$(cat $WATCHDOGPIDFILE)
            if [ $(ps -o pid | grep $PID) ]; then
                exit 0;
            fi
        fi

        touch $WATCHDOGPIDFILE

        echo $$ > $WATCHDOGPIDFILE

        #trap the interruption or kill signal
        trap stopdaemon INT SIGINT TERM SIGTERM

        start

        while true; do
            keep_alive
            wait
            sleep 1
        done

    ;;

    x-stop )

        echo "Stopping daemon watchdog"
        PID=$(cat $WATCHDOGPIDFILE)
        kill $PID

    ;;

    x-status )
        #check if process is running and PID file exists, and report it back
    ;;
    x )
        echo "Usage {start|stop|status}"
esac

exit 0