Website Offline Holding Pages with PHP – Doing it Right!

When making major changes to your website it’s usually a good idea to put up holding pages. This is for many reasons, but mainly so that whilst your update is taking place, no-one tries to use your website and finds it broken.

This article makes the assumption that you have ssh access to your webserver. Most web hosting companies offer ssh access and it’s absolutely paramount that you have ssh access the purposes of this article. You can test if you have ssh access by typing ssh your-ftp-username@www.yourdomain.com in a linux terminal window or trying to connect to your www.yourdomain.com using a windows client such as PUTTY. If you have root access, switch to your website’s user:

shell [root] ~$ su <inert-user-name-here>

Let’s assume that you use a cPanel server and that your main document root folder (the one that the website browser can access) is public_html. We are going to move your main files from living in the public_html folder to now live in a new folder called public. We will then create a symbolic (soft) link from your public_html folder to your newly created public folder.

Why? Your website’s document root folder is specified in your apache config files as /home/[your-user-id]/public_html. By making this folder a symbolic link to your actual public means that it can be removed and pointed somewhere else if needed. Confused? Read on – all will become clear.

In your shell do this:

shell ~$ mv public_html public
shell ~$ ln -s public public_html

Now create a folder called holding, again using terminal:

shell ~$ mkdir holding

Create a file in the newly created holding folder called index.php:

shell ~$ nano -LwE holding/index.php

Put the following in the file:

<?php
    header('HTTP/1.1 503 Service Temporarily Unavailable');
    header('Status: 503 Service Temporarily Unavailable');
    header('Retry-After: 3600');
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Website Unavailable</title>
    </head>
    <body>
        <h1>Website Unavailable</h1>
        <p>Our website is available due to essential maintenance.</p>
    </body>
</html>

We have added a 503 Service Temporarily Unavailable (apache.org definition) header and we have also added a retry-after response header and 3600 delta-seconds which is 1 hour.

Now you have a default index file in your holding folder that gives the correct 503 Service Temporarily Unavailable response header.

But wait, this will only work if someone visits your home page. We also have to make sure that all other page requests give correct 503 Service Temporarily Unavailable response header. We do this by using a .htaccess file as follows:

shell ~$ nano -LwE holding/.htaccess

Add the following:

RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !index.php
RewriteRule ^(.*)$ http://www.yourdomain.com/index.php [R=302,L]

This will redirect, temporarily, all requested pages to the 503 Service Unavailable page.

Finally, swap your apache document root to point to holding instead of public

shell ~$ cd ~
shell ~$ unlink public_html
shell ~$ ln -s holding public_html

And – to swap this back, simply do this in reverse:

shell ~$ cd ~
shell ~$ unlink public_html
shell ~$ ln -s public public_html

Permalink: http://www.websitefactors.co.uk/php/2011/08/website-offline-holding-pages-with-php-doing-it-right/

This entry was posted in PHP. Bookmark the permalink.

2 Responses to Website Offline Holding Pages with PHP – Doing it Right!

  1. Shane Rutter says:

    This is a very good post which I think i will be using the in the future.

    The amount of times I have been doing website updates and I receive an email telling me something isn’t working or looking right.

    I think as long as the website isn’t offline for hours which shouldn’t really effect SEO.

    • Henry Hayes says:

      Well actually the point of the 503 response is so that Google (and other search engines) come back later.

      <?php
          header('HTTP/1.1 503 Service Temporarily Unavailable');
          header('Status: 503 Service Temporarily Unavailable');
          header('Retry-After: 3600');
      ?>

      The mistake people sometimes make is serving a 500 error. Google (and other search engines) know that you would have to intentionally serve a 503, whereas a 500 error would automatically be served by apache.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Notify me of followup comments via e-mail. You can also subscribe without commenting.