I am Hack Sparrow
Captain of the Internets.

Make Forever.js Reboot-Proof with Cron

Start Forever.js on System Restarts

Some time ago, I wrote a post on keeping Node.js apps running even after logging out from the shell. It was cool and all, but soon you will soon realize that Forever alone is not enough. Because, on system reboots, Forever itself is killed. Who will restart your app now?

There are many options for handling this kind of scenario, but today we will implement a solution using cron. Let's find out how we can make Forever and our Node.js app reboot-proof.

The app you want Forever to start on system restart is probably a web app, so let's try this thing on an Express.js web app.

Install Express, if you haven't already:

$ npm install -g express

Now, create an Express app:

$ mkdir example
$ cd example
$ express

There we have our Express app. It should be started using Forever - on system reboots - automatically.

First we need to write a bash script to check if our app is running or not; if it is not running, it should start the app using Forever. Create a file named app-starter.sh in your home directory with this content:

#!/bin/sh

if [ $(ps aux | grep $USER | grep node | grep -v grep | wc -l | tr -s "\n") -eq 0 ]
then
export NODE_ENV=production
export PATH=/usr/local/bin:$PATH
forever start ~/example/app.js > /dev/null
fi

Note how we augmented the environment variables in the script. Those are crucial to making the script work successfully from cron. Change the NODE_ENV variable, according to your requirement. /usr/local/bin needs to be added to PATH, else Forever just won't work on most systems.

Next, make the script executable:

$ chmod 700 ~/app-starter.sh

Then, run it and load http://localhost:3000 on your browser to confirm it actually started our app using Forever:

$ ./app-starter.sh

Looking good. Now it's time to make cron do the job for us. We want to make sure that the app-starter script is execute when the system is rebooted. Append the following code to crontab:

@reboot ~/app-starter.sh >> cron.log 2>&1
# guess what the commented line below would do if enabled
# */1 * * * * ~/app-starter.sh >> cron.log 2>&1

To open crontab:

$ crontab -e

After making changes to crontab, restart your system.

Load http://localhost:3000 on your browser to behold the magic of Forever + cron 😀 Now you don't have to worry about system restarts taking your app down, anymore. cron takes care of Forever, and Forever takes care of your app; and you win at life!

While this example is perfect for a single app, you will need to hack the app-starter script to make it work for more than one Node.js app. How to do that is your homework. All the best!

9 Responses to “Make Forever.js Reboot-Proof with Cron”

  1. Ross says:

    instead of grep-ing `node`, if may be better to grep for the app name?

    if [ $(ps aux | grep $USER | grep my_app.js | grep -v grep | wc -l | tr -s “\n”) -eq 0 ]

  2. Captain says:

    Yes you could, and probably should. What I showed is more of a pointer, than a best solution.

  3. Forever problem says:

    forever list command shows 10 same apps running at the same time. The fuck is that?

  4. Henrik says:

    This is pretty inefficient. Now you’ve got a cron job with a script listing all processes and performing a lot of filtering just to see if an app with the word ‘node’ in it is running, every minute, every day, etc.
    This also means the script will restart the app whenever it’s not running, even if Forever has just noticed it’s dead and is about to do the same thing, which could explain the problem mentioned above.

    Why not just write an init script for Upstart, systemd, or whaterver your server uses? Then you can also make sure it doesn’t try to launch the app before all dependencies are up.

  5. Captain says:

    Hi Henrik, I agree with you – using upstart might be the best option, when it is available. This one is just a go at a solution using cron.

  6. Jeff says:

    Hmm. works great for me!

  7. Christian Fei says:

    Thank you so much for this tutorial, the only one I found that suited my need and was dead simple with cronjobs!

  8. Akseli Palen says:

    @Henrik, I disagree. The script can’t restart the app while Forever has just noticed it’s dead. This is true because Forever is a node process too and the script first calculates the number of running node processes and checks if the result equals to zero. Therefore the lines inside the if clause will not be executed if Forever is running.

  9. Charlie says:

    I would recommend using Upstart (on Ubuntu) or systemd (on other flavors of Linux). The systemd config file is actually easier to write than this cron script and far more reliable. I suppose this works fine as a quick solution for development though.

Make a Comment