When working with Nodejs starting your applications and keeping them running is not always straightforward. There are tools to help you with this, like forever and pm2, but if you are doing any kind of deploy-and-build step you will need to have more of a plan than "run the application."

My application server management consists of five pieces

The application directory structure

Shell scripts to manage the individual application

A git repository with a post-receive hook

A shell script to manage all applications

Cron to make sure everything stays up and starts after a reboot

Application structure on the server

A consistent directory structure will help keep you sane as the number of projects on your server grows. Here is what I use

~/
|- /git
| +- /project.git
+- /webapps
+- /project
|- /app
+- /run

The git repository holds the source code. The /webapps directory has a project folder for every project. The /project/app directory holds the actual application code. The /project/run directory holds several scripts that control the application.

Shell scripts for the application

I use five shell scripts to manage every application. If I ever take some time to learn bash better, I will condense them down to one script with flags, but I am not there yet. To simplify project setup, all five can be downloaded and Regexed (sed) into place with this command.

I have these scripts to encapsulate application control. They are called from various places, and if individual applications have special constraints, or all applications need to change, I only need to make changes to these scripts. Some of them, like the one-line stop may seem like overkill, but if I ever switch from forever to pm2 its going to save me a lot of headaches to only update a couple stop scripts.

These are the scripts.

./start

The start script is a safe-for-cron script. It can be run and re-run without any negative side-effects, because it checks to see if the app that it's about to start is running before trying to actually start it.

./restart-install

Since the app needs to install in-betweenstop and start, the restart script can't be used (which is part of what really limits its utility). This is the script that is actually called from git's post-receive hook.

A shell script for all applications

Now some people skip this step and just load the start script for each application into their cron jobs. I don't like doing this, because I want to run cron every fifteen minutes and after reboot. This would mean writing the call to the start script twice, for each application. Instead, I wrap all of them into one script.

apps=(
"blog"
"portfolio"
"home"
#etc...
)
for i in "${apps[@]}"
do
/home/tyrsius/webapps/$i/run/start
done

This has the added advantage of the very clean "one app per line" format that the apps array loop gives us. Also, because each start script is safe to run multiple times, so is this script.

Cron jobs

Last, but certainly not least, is the cron job that makes sure the apps are always running.

It's simple, and it never needs to grow. When new apps are added, they go into start-all-apps.

The PATH for cron jobs won't include node normally, which I why I have to manually set the path at the top; otherwise, the start script calls to forever will fail.

Spinning up new apps

This can all be done manually, without too much effort. However, as a developer, I prefer to automate as much as possible. WIth that in mind, I have a script that will create a new project directory, a new git repo, and even add an entry to start-all-script for me. Its long, and uses scripts I have stored on GitHub, but you might find it interesting.