Displaying a Maintenance Page for Your Web Site

Update: I found what appears to be a much easier maintenance page setup in the book Agile Web Development with Rails, second edition, page 626, in the section titled "Step Five: Connect Apache to Mongrel". When I try it out, I'll post my results here.

I want to display a page that tells visitors that my site is down for maintenance. From users' perspective, any normal page they try to access will display a maintenance page instead of the page they expected. However, I still want see the normal site while it is under maintenance so I can test it before making it live again.

I have Apache with mod_rewrite. Here's how I did it for www.moxleystratton.com:

  1. Create a new subdomain of moxleystratton.com in my DNS:
    maint.moxleystratton.com
    1. Change to root user
    2. Edit /var/named/chroot/var/named/db.moxleystratton.com
    3. Copy the line that starts with www.moxleystratton.com and paste it to a new line, one below.
    4. Rename www.moxleystratton.com to maint.moxleystratton.com.
    5. Swap out the serial number (roughly the 3rd line in the file)
      with a new timestamp, using this format: YYYYMMDDNN, where NN is
      a revision number, starting with "00", and incrementing for each
      revision within a given day.
    6. Restart named: /etc/init.d/named restart
  2. Create a web documents folder for what will be the maint.moxleystratton.com web site. I chose /home/vwww/www.moxleystratton.com/maint_htdocs. This will hold the files to be served when the site is under maintenance. When moxleystratton.com is not under maintenance, I can see the maintenance version at http://maint.moxleystratton.com/, so it can be tested.
  3. Add an Apache virtual host for the maintenance site. It is easy to just copy the virtual host definition of the main site and make the necessary changes. Here's mine, approximately:
    <VirtualHost 66.135.33.108:80>
    	ServerName maint.moxleystratton.com
    	ServerAdmin root@server1.moxleydata.com
    	ServerAlias moxleystratton.com
    	DocumentRoot /home/vwww/moxleystratton.com/maint_htdocs
    	ErrorLog /home/vwww/moxleystratton.com/logs/error_log
    	CustomLog /home/vwww/moxleystratton.com/logs/access_log combined
    	<Directory /home/vwww/moxleystratton.com/maint_htdocs/>
    		Allow from all
    		AllowOverride All
    		Order allow,deny
    	</Directory>
    </VirtualHost>
    
  4. Restart Apache
  5. You should now be able to visit the maintenance site from your browser: http://maint.moxleystratton.com
  6. Create the maintenance HTML page using the regular home page has a starting point. I went to the maint_htdocs folder and ran this command: wget http://www.moxleystratton.com/. It saved the home page as index.html.
  7. Save or symbolically link any CSS or images the maintenance page will need as well.
  8. Here are the symbolic links I set up:
    1. cd maint_htdocs
    2. ln -s ../htdocs/images images
    3. ln -s ../htdocs/misc misc
    4. ln -s ../htdocs/themes themes
  9. Add an .htaccess file to the maintenance site that looks like this:
    # Maintenence rewrite rules
    #   If the file exists, serve it
    #   Else, show the maintenance page (/index.html)
    <IfModule mod_rewrite.c>
      RewriteEngine on
    
      RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}  !-f
      RewriteRule ^(.+) /index.html [L]
    
      RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
      RewriteRule ^(.+) %{DOCUMENT_ROOT}/$1 [L]
    </IfModule>
    

    This will make any request to the maintenance site result in the display of index.html, except for the files that are actually on the maintenance site. Go ahead and try it. Enter a path that doesn't exist, like http://maint.moxleystratton.com/asdf

  10. Make a backup of the Apache configuration for the main site, so that you will have it available to quickly take the site out of maintenance mode. The next two instructions temporarily change the main site's
    configuration.
  11. Give visitors to the main site access to the maintenance site files:
    In the Apache configuration for the maintenance site, copy the <Directory> element from
    the maintenance site's virtual host definition, and paste it into the main site's definition,
    so now there is another <Directory> directive in the main site.
  12. Change the <DocumentRoot> directive of the main site to point to the maintenance site's document root.
  13. Add this to your main site's definition:
    # Maintenance rewrite rules
    #   Show the main site only for one IP address
    <IfModule mod_rewrite.c>
      RewriteEngine on
    
      RewriteCond %{REMOTE_ADDR} ^67.164.53.225$
      RewriteRule ^(.+) /home/vwww/moxleystratton.com/htdocs/$1 [L]
    
    </IfModule>
    

    This gives only one IP address access to your main site. Change the IP address above to match your own.

    Here's my main site's configuration after the changes:

    <VirtualHost 66.135.33.108:80>
    	ServerName www.moxleystratton.com
    	ServerAdmin root@server1.moxleydata.com
    	ServerAlias moxleystratton.com
    	DocumentRoot /home/vwww/moxleystratton.com/maint_htdocs
    	ErrorLog /home/vwww/moxleystratton.com/logs/error_log
    	CustomLog /home/vwww/moxleystratton.com/logs/access_log combined
    	<Directory /home/vwww/moxleystratton.com/htdocs/>
    		Allow from all
    		AllowOverride All
    		Order allow,deny
    	</Directory>
    	<Directory /home/vwww/moxleystratton.com/maint_htdocs/>
    		Allow from all
    		AllowOverride All
    		Order allow,deny
    	</Directory>
    
    	# Maintenance rewrite rules
    	#   Show the main site only for one IP address
    	<IfModule mod_rewrite.c>
    	  RewriteEngine on
    
    	  RewriteCond %{REMOTE_ADDR} ^67.164.53.225$
    	  RewriteRule ^(.+) /home/vwww/moxleystratton.com/htdocs/$1 [L]
    	</IfModule>
    
    </VirtualHost>
  14. Restart Apache. Your site is now in maintenance mode.
  15. When you are done with maintenance mode, restore the Apache config from the backup created earlier, and restart Apache.