Nginxを使ってアプリケーションのメンテナンスモード設定をする

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

アプリケーションを運用していくと、新機能の追加、変更時にいきなり全ユーザーにアプリケーションを公開するのではなく、
メンテナンスモードにして特定の場所(開発拠点など)からのみページを参照できるようにして、機能の確認を行いたい場合があると思います。
今回はWebサーバにNginxを使っている場合の設定方法の例をご紹介します。

Nginxの設定

アプリケーション構成

WebサーバにNginx、ApplicationサーバにUnicornを使ったRailsアプリケーションです

役割 名称
Webサーバ Nginx
Applicationサーバ Unicorn

通常時の設定

今回の説明に必要な箇所だけ書くと次のようになります。
Unicornに飛ばすリクエストのURIはここでは/api/*としています。
(今回の例では、静的ファイルは全て/path/to/application_dirに配置、APIはRailsで担当するSPAアプリケーションです)

upstream unicorn {
    server unix:/tmp/unicorn_app.sock;
}

server {
    listen       80;
    server_name  localhost;
    
    location / {
        root   /path/to/application_dir;
        index  index.html index.htm;
    }

    location /api/ {
        proxy_pass http://unicorn/api/;
    }

   # この後にもエラーページ設定などいろいろ
}

メンテナンスモード時の設定

メンテナンスモードで実現したいことは以下です。

場所 動作内容
開発拠点 通常どおりアプリケーションを見れる
その他の場所 リクエストは全てメンテナンス用ページにリダイレクトさせる

それでは設定ファイルにメンテナンスモードの記述を追加していきます。

静的ファイルへのリクエストの設定

事前の作業としてリダイレクト先のページを「maintenance.html」としてこれを静的ファイル用のディレクトリ(/path/to/application_dir)に配置しました。
設定ファイルには次の二つの記述を追加します。

  • 開発拠点のIPアドレスからのアクセスはリダイレクトさせないようにする
  • それ以外のリクエストは「/maintenance.html」にリダイレクトさせる(css, imageファイルはmaintenace.htmlで使うのでリダイレクト対象外にしました)
location / {
    root   /path/to/application_dir;
    index  index.html index.htm;
    # ここから追加、開発拠点のアドレスは対象外にする(0.0.0.0)
    if ($remote_addr ~ ^(0\.0\.0\.0)$) {
        break;
    }
    # その他の場所からのリクエストは/maintenance.htmlにリダイレクトさせる
    # リダイレクト先を同じアプリケーションではなく別のドメインのページにする場合は「/maintenance.html」の箇所を
    # そのドメインに変更します)
    rewrite ^/(?!css|image).*$ /maintenance.html break; #redirect maintenance screen
}

rewriteの行の最後の「break」を忘れるとrewriteの無限ループ(実際は10回で止まる)が発生するので気をつけて下さい。

Unicornへのリクエストの設定

ここでは開発拠点以外のアドレスからのリクエストをUnicornに送らないようにします。

location /api/ {
    # ここから追加、開発拠点以外のアドレスはunicornにリクエストを送らずにアプリケーションのトップにリダイレクトさせる
    # アプリケーションのトップページから「/maintenance.html」に再度リダイレクトされる
    if ($remote_addr !~ ^(0\.0\.0\.0)$) {
        return 301 https://localhost;
    }
    # ここまで   
    proxy_pass http://unicorn/api/;
}

ELBを使っている場合

最後におまけですが、AWS上でELBを使って構築する場合の設定です。
ELBを使うと、Nginxで受け取るアクセス元のIPアドレスはELBのアドレスになります。 そしてELBはヘッダーのX−Forwarded−Forに本来のリクエスト元のIPアドレスを格納するので、NginxでこのアドレスをリアルIPとして扱うように設定をします。

設定する内容

設定する項目は次の二つです。

名称 設定する内容
set_real_ip_from ELBのIPアドレス。VPCの場合はELBのサブネットアドレス
real_ip_header IPが設定されているヘッダーの名称(X-Forwarded-for)
server {
    listen       80;
    server_name  localhost;
    
    # ここから追加
    set_real_ip_from   10.0.0.0/8;
    real_ip_header     X-Forwarded-For;
    
}

上記の内容を追加してあげれば、ELB使用時にもメンテナンスモード用の設定が正常に動作するようになります。