メンテナンス画面の設置のお作法

2014年4月1日の消費税率改定に伴うシステムメンテナンスの案内が、各種ECサイトで行われています。
大手サイトでも、 2014年3月31日(月)15:00 ~ 2014年4月1日(火)10:00の間 サイト停止など税率変更の作業には時間を要します。
さて、メンテナンス画面を表示させておくにはどうすればよい?という質問に答えます。
方法1.プラグインを利用する
2.12系以上であれば、メンテナンス切り替え機能プラグイン
を利用できます。
プラグインをインストールすると、基本情報管理にメンテナンス管理メニューが現れますので
通常営業中かメンテナンス中を設定できます。
メンテナンス中のメッセージも設定できますので、画面デザインを凝らずサクッと対応するにはプラグインを導入してみてはいかがでしょうか。
方法2. .htaccessを設定する
メンテナンス画面のデザインを自由に設定したい
特定のIPからはメンテナンス画面を表示したくない
指定の期間だけメンテナンス画面を表示させたい
など、細かい要件に対応するには、.htaccessを変更する方法がよいでしょう。
用意するファイルは3つ

  • .htaccess
  • 503.php
  • maintenance.html

です。

ここでは、
2014年3月31日15:00 ~ 2014年4月1日10:00の間
メンテナンス画面(maintenance.html)を表示させる
ただし、管理画面にはアクセスでき
特定IP(203.0.113.0)からはフロント画面も閲覧できる
という条件で、ファイルを記述してみましょう。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/503.php
RewriteCond %{REQUEST_URI} !^/maintenance.html
RewriteCond %{REQUEST_URI} !^/admin/
RewriteCond %{REQUEST_URI} !^/user_data/
RewriteCond %{REMOTE_ADDR} !=203.0.113.0
RewriteCond %{TIME_YEAR}%{TIME_MON}%{TIME_DAY}%{TIME_HOUR}%{TIME_MIN} >201403311500
RewriteCond %{TIME_YEAR}%{TIME_MON}%{TIME_DAY}%{TIME_HOUR}%{TIME_MIN} <201404011000
RewriteRule ^.*$ /503.php [L]
</IfModule>

.htaccess

<?php
header ('HTTP/1.0 503 Service Temporarily Unavailable');
readfile(dirname(__FILE__) . '/maintenance.html');
?>

503.php

<html>
 :
 画像やcssはすべて/user_data/配下のファイルを参照する
 :
</html>

maintenance.html
以上で、条件を満たしたメンテナンス画面を表示できます。

.htaccessのリライトルールの記述
RewriteRule ^.*$ /503.php [L]
の箇所は、
RewriteRule ^.*$ - [R=503,L]
と503のレスポンスを返し、
503レスポンス時の画面として
ErrorDocument 503 /maintenance.html
と設定することも可能です。

 
ただし、Apacheのバージョンによっては、400以上のレスポンスコードを返せず
RewriteRule: invalid HTTP response code for flag 'R'
エラーが発生するケースもあるため、
503.phpでリライトし、503.phpで503レスポンスを返しています。

 
メンテナンス画面をステータスコード200で表示させると、サーチエンジンにインデックスされるため、
503のステータスコードを返すのがお作法です。
 
また、よくやってしまいがちなのが、メンテナンス画面(とその画像)をリライトコンディションに含めず、無限ループに陥って
mod_rewrite: maximum number of internal redirects reached.
エラーが返るパターンです。
今回の場合は、
RewriteCond %{REQUEST_URI} !^/503.php
RewriteCond %{REQUEST_URI} !^/user_data/
とすることで、メンテナンス画面と参照する画像/cssだけはそのまま表示させるようにしています。