How to automatically restart Apache/Nginx service when your website goes down using CRON

red and blue arrow sign surrounded by brown trees

If you need to do a simple heartbeat check on a basic web server, Apache or Nginx, and automatically restart the server when you no longer receive 200 responses this simple CRON script might be what you need. However, I do not recommend this as a long-term solution.

The script does a few things:

  1. Check a URL, that must be hosted on the server, for a 200 response.
  2. If there is no 200 response it created a site_down file.
  3. If the site_down file is 10 minutes old and the server is still not responding with a 200 code it will reboot the web server.
  4. If the site comes back online, it will remove the site_down file to avoid needed reboots.

Modify this script to your server’s needs and then run it via CRON every minute or two. I run it every two minutes */2 * * * * but your needs may differ.

#!/bin/sh
# Your heartbeat URL here (must be hosted on this server)
URL_TO_CHECK="https://example.com"
# Your temp file to monitor downtime
DOWN_FILE="/root/site_down";
# How long will you tolerate downtime in minutes
DOWN_TIME="+10";

HTTP_STATUS=`curl -s -o /dev/null -w "%{http_code}" "$URL_TO_CHECK"`;
SITE_DOWN_TOGGLE=`find "$DOWN_FILE"`;

echo "$SITE_DOWN_TOGGLE";

if [ "$HTTP_STATUS" != "200" ]; then
    echo "Website is down $HTTP_STATUS";
    if [ "$SITE_DOWN_TOGGLE" != "$DOWN_FILE" ]; then
        touch "$DOWN_FILE";
        echo "Made file $DOWN_FILE";
    fi

    SITE_DOWN_PAST_TIME=`find "$DOWN_FILE" -mmin "$DOWN_TIME"`;

    if [ "$SITE_DOWN_PAST_TIME" = "$DOWN_FILE" ]; then
        rm "$DOWN_FILE";
        echo "Site down past timecheck... rebooting apache";
        
        # IMPORTANT: Choose or add a the line below with web server's restart command 
        # CentOS: apache 
        # sudo systemctl restart httpd.service
        
        # Ubuntu: apache
        # sudo systemctl restart apache2

        # Ubuntu: nginx
        # sudo systemctl restart nginx
    else
        echo "Site not yet down past $DOWN_TIME tolerance";
    fi
else
    rm "$DOWN_FILE";
    echo "Website is running $HTTP_STATUS";
fi

Next, I SSH into the server and edit the crontab with crontab -e. Now, I can set the interval to 2 minutes with */2 * * * *. Here is what that might look like, note your path and file name will differ.

*/2 * * * * /root/web_server_heartbeat.sh >/dev/null

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.