Redmineにはバナープラグインがあって、メンテナンス作業の予告を利用者に通知するのに活用しています。
https://github.com/akiko-pusu/redmine_banner
しかし、いざメンテナンス作業でRedmineを止めてしまうと、Webサーバーへのアクセスが内部エラー表示となってしまいます。Nginx + Unicorn でRedmineを動かしている場合、Unicornを停止するとNginxは、「Internal error」を表示します。
これは、メンテナンス作業中であることや終了予定日時を示すページを表示したいところです。
そこで、試行錯誤を始めました。Nginxでメンテナンスページ表示を検索すると、方法を紹介するページが多数ヒットしますが、それぞれ微妙に方法が異なります。見よう見真似で試してみますがどうもうまくいきません。
最小限の措置: 503エラーページを強制表示
とりあえず、/etc/nginx/conf.d/redmine.conf に無理やり1行追加で503エラーとしました。
server { listen 80; server_name _; root /var/lib/redmine/public; client_max_body_size 1G; return 503;
このように、return 503を有無を言わせず入れたら、
503 Service Temporarily Unavailable ------------------------------------ nginx/1.11.1
という表示が出ました。
if文でファイル存在をチェックする方法が機能せず
server { listen 80; server_name _; root /var/lib/redmine/public; client_max_body_size 1G; if (-e /var/tmp/do_maintenance) { return 503; }
と、/var/tmp/do_maintenance ファイルがあるかをチェックして、あれば503エラーとするようにしたのですが、このif文がなぜか機能しませんでした。
うーむ。
maintenance.htmlがあるときはそれを表示、なければ通常通り
次のブログに、「ファイルがあれば表示、なければbackendに流す」という例がありました。
mod_rewriteをnginxに移植するコツはifを使わないコト! - インフラエンジニアway - Powered by HEARTBEATS
それを見て
root /var/lib/redmine/public; : location / { try_files $uri/index.html $uri.html $uri @app; }
を
root /var/lib/redmine/public; : location / { try_files /maintenance.html $uri/index.html $uri.html $uri @app; }
に修正し、/var/lib/redmine/public/maintenance.html を作成すると、maintenance.htmlの内容が表示されました。
これでいけそうです。