はじめに
以前書いた記事で、「nginxでメンテナンスページを表示させる。」というのがあるのですが、もっと良いやり方があったので改めて書きます。
設定
とりあえず設定内容です。今回もmaintenanceというファイルをincludeしている前提で進めます。
error_page 500 @maintenance;
# Set Env
set $maintenance "on";
# Allow Paths
if ($uri ~ "^/exclude/") {
set $maintenance "off";
}
# Allow IPs
if ($remote_addr ~ "xxx.xxx.xxx.xxx") {
set $maintenance "off";
}
if ($http_x_forwarded_for ~ "xxx.xxx.xxx.xxx") {
set $maintenance "off";
}
# maintenance
if ($maintenance = "on") {
return 500;
}
location @maintenance {
rewrite ^(.*)$ /maintenance.html break;
}
# include /etc/nginx/conf.d/maintenance;
rewrite ^/maintenance.html(.*)$ https://$host/ permanent
説明
まず初めの1行目のerror_page 500 @maintenance;
というところでリターンコード500の場合@maintenance
というところへリライトするように設定しています。
このリライト先というのが一番下のlocation
ブロックです。
次にset $maintenance "on";
で変数$maintenance
にon
という値をセットしておきます。
以下の部分ではif文を利用し、Allow Pathsの部分では特定パスへのアクセスに対して$maintenance
をoff
に、Allow IPsの部分では特定IPからのアクセスに対し$maintenance
にoff
を設定し直すように記載されています。
そして最後のところで$maintenance
がon
ならリターンコードとして500を返すようにしています。
そうすることでメンテナンスを有効にしてもメンテナンスページへリダイレクトされるのではなくメンテナンスページのリライトで済みます。解除すると先ほどアクセスしていたパスが表示されます。
また、nginx.confの方ではinclude /etc/nginx/conf.d/maintenance;
をコメントアウト(#)付きで記載しておき、#の付け外しで制御するようにしています。
また、その下のrewriteルールでmaintenance.htmlへのアクセスは無条件にサイトのトップへリダイレクトさせることで何か間違ってメンテナンスページへ直接アクセスしてしまった相手に対しての対処もしています。
おわりに
リダイレクトとリライトをうまく駆使することがポイントだなと感じました。