Watching Web Services Using Crontab

A bare bones way to monitor your web services and restart them when necessary

There are many web hosting services that provide ways to monitor your running server and restart it when necessary. But not all of them do, and if you’re stuck like I was on a shared server with no such fancy pants watcher, you may find this simple method using common tools useful.

Step 1: Write a Watcher Script

The watcher script simply runs one time and checks if a server process is running, and if it isn’t, starts it.

In my case, I needed to manually set my $PATH variable, otherwise the cron job wouldn’t be able to run node:

1
2
3
4
# set PATH so cron job can find and execute 'node'
#
PATH="/home/ss_server/.nvm/versions/node/v14.15.0/bin:/usr/local/bin:/usr/bin:/bin:"
echo " which node: $(which node)"

The next part of the script uses the ps aux command to see if my server processes are running. If all are running, the script exits early.

In my case, I am looking for two processes: index.js and encrypt.js:

1
2
3
4
5
6
7
8
9
10
11
#
# find out if services are already running
#
echo " checking if services are already running..."
HAS_INDEX=$(ps aux|grep "index.js"|grep -v "grep"|wc -l)
HAS_ENCRYPT=$(ps aux|grep "encrypt.js"|grep -v "grep"|wc -l)
(( HAS_BOTH = $HAS_INDEX + $HAS_ENCRYPT ))
if [[ $HAS_BOTH == 2 ]]; then
echo " both services are already running, bye."
exit 0
fi

This one liner bears some explanation:

1
$(ps aux|grep "index.js"|grep -v "grep"|wc -l)

It evaluates to 1 if “index.js” is running, 0 if it’s not. (the grep -v "grep" bit is needed, because the prior grep "index.js" often shows up as a process in ps aux).

The remainder of the script simply restarts my server processes:

1
2
3
4
# using pm2, delete then restart my server processes
/home/ss_server/ss-server.terrymorse.com/pm2 delete all
/home/ss_server/ss-server.terrymorse.com/pm2 start \
/home/ss_server/ss-server.terrymorse.com/pm2-simple-server.config.js

Step 2: Add a cron job using crontab

Use crontab -e to add a cron job single line that will run my script every minute, logging stdout and stderr:

1
2
3
4
5
#
# watch the ss-server services once per minute
* * * * * /home/ss_server/watch-services.sh \
>> /home/ss_server/logs/watch-services.log \
2>>/home/ss_server/logs/watch-services.error.log

Bottom Line

With just a simple script and one cron job line, I now have a watcher that restarts my web services whenever necessary. Which is pretty important, because the shared server I’m using reboots often, but it doesn’t restart my services.