nginxでメンテナンスページ用意する技

LT;DR

かっぱ先輩!

かっぱ先輩のブログを読んで

同じようなことを最近やっていたのでメモ。

追記(03/12) 14:00

  • リダイレクトやめましょうとのこと
  • 503でお返事しましょうとのこと

ノーSEO(disallow: /)だったので完全に無視してた

nginxに設定しているメンテナンスモードの条件

  • /var/nginx/html/maintenance/maintenance.htmlファイルがあればメンテナンスモードとしてmaintenance.htmlを表示するように

  • /healthcheckのリクエストはメンテナンスモードでも通す

  • 管理IPアドレスからはメンテナンスモードでも通す

という3点を設定しています。

  • nginx.conf
upstream example_pool {
    server 127.0.0.1:3000;
}

geo $allow_ip_flag {
    default 0;
    192.0.2.0/24 1;    #TEST-NET-1
    198.51.100.0/24 1; #TEST-NET-2
}

server {
    listen       80;
    server_name  example.com;

    access_log  /var/log/nginx/example_com_access.log  ltsv;
    error_log  /var/log/nginx/example_com_error.log warn;

    root /var/nginx/html/example;

    location /robots.txt {
            alias /var/nginx/html/robots.txt;
    }

    location / {

        ### メンテナンスの設定 ここから ###############################
        if ( -e /var/nginx/html/maintenance/maintenance.html ) {
            set $maintenance true;
        }

        # health checkのリクエストはログに出さずに
        # メンテナンスページを通過する
        if ( $request_uri ~ /healthcheck ) {
            set $maintenance false;
            access_log off;
        }

        # 許可IPアドレスならメンテナンスページを通過する
        if ( $allow_ip_flag ) {
            set $maintenance false;
        }

        # それ以外は/maintenance.htmlに飛ばす
        if ( $maintenance = true ) {
            rewrite ^ /maintenance.html redirect;
        }

        location /maintenance.html {
            alias /var/nginx/html/maintenance/maintenance.html;
            expires 0;
        }
        ### メンテナンスの設定 ここまで ###############################

        proxy_pass http://example_pool;

        proxy_set_header Host              $http_host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;

        client_max_body_size 710M;
        proxy_connect_timeout      3000;
        proxy_send_timeout         3000;
        proxy_read_timeout         3000;
        break;
    }
}

nginxは複数の条件の場合bit立てて判断するの知らなかった。

こういうのはエレガントにngx_mrubyでやった方が運用楽そう。