ようへいの日々精進XP

よかろうもん

深夜メンテナンスに役立ちそうな nginx 小ネタ

はじめに

  • nginx を使っている場合にサービスのメンテナンス等に役立ちそうな小ネタ
  • 他にもネタがあれば随時書く

小ネタ #1 設定に if が利用出来る

設定に if が使える

良く知られたことなのかもしれないが、nginx の設定には if が使えるので深夜メンテナンス等で特別な処理を噛ませたい場合には以下のように出来る。

    location / {
        root   html;
        index  index.html index.htm;
        if (-f "/tmp/maintenance" ) {
                  rewrite ^(.*)$ http://172.17.0.3:8000/maintenance.html permanent;
        }
    }

上記の例だと /tmp/maintenance にファイルを touch すると...

http://172.17.0.3:8000/maintenance.html

にリダイレクトされる。


小ネタ #2 メンテナンス画面に飛ばす時にパラメータは付けたくない

要望

  • ユーザーがアクセスした際にメンテナンス画面(maintenance.html) に飛ばしたい
  • でも、余計なパラメータは付けたくない(hoge.com/huga.html?baz => hoge.com/maitenance.html?baz とかにしたくない)

方法

以下のように設定する。

    location / {
        root   html;
        index  index.html index.htm;
        if (-f "/tmp/maintenance" ) {
                  rewrite ^(.*)$ http://172.17.0.3:8000/maintenance.html? permanent;
        }
    }

リダイレクト先の URL の末尾に ? を付けるだけ。

デモ

? 無し。

f:id:inokara:20140222125632p:plain

以下のように設定して...

rewrite ^(.*)$ http://172.17.0.3:8000/maintenance.html permanent;

アクセスすると...

f:id:inokara:20140222125647p:plain

見事にパラメータ(?hoge)が引き継がれている。

? 有り。

f:id:inokara:20140222125657p:plain

以下のようにして...

rewrite ^(.*)$ http://172.17.0.3:8000/maintenance.html? permanent;

アクセスすると...

f:id:inokara:20140222125708p:plain

見事にパラメータが無くなっている。

参考(※追記)

ちなみにドキュメントに以下のように記載されていた。

If you specify a ? at the end of a rewrite then Nginx will drop the original $args (arguments). When using $request_uri or $uri&$args you should specify the ? at the end of the rewrite to avoid Nginx doubling the query string.

おお、面白い仕様だな。


小ネタ #3 特定の接続元からのみメンテナンスページをスキップさせて通常ページを見せたい

要望

  • メンテナンス作業がひと通り終わった後でユーザーに公開する前に一部の接続元から動作確認したい

方法

以下を実現するには...

  • $remote_addrxxx.xxx.xxx.xxx の IP アドレスからの接続はメンテナンスページに飛ばさない
  • それ以外の IP アドレスからは引き続き、メンテナンスページに飛ばす
    location / {
        root   html;
        index  index.html index.htm;
        if ($remote_addr ~ ^172\.17\.42\.1$) {
                  break;
        }
        if (-f "/tmp/hoge" ) {
                  rewrite ^(.*)$ http://172.17.0.3:8000/maintenance.html? permanent;
        }
    }

デモ

f:id:inokara:20140222133457p:plain

breakコメントアウトして...

        if ($remote_addr ~ ^172\.17\.42\.1$) {
        #         break;
        }

/etc/init.d/nginx restart する。

見事にメンテナンスページに飛ばされた。

f:id:inokara:20140222133511p:plain

そして、break を有効にする。

        if ($remote_addr ~ ^172\.17\.42\.1$) {
                 break;
        }

そして、/etc/init.d/nginx restart する。

f:id:inokara:20140222133537p:plain

メンテナンスページにはリダイレクトされずに通常のページが表示される。

メモ

  • こちらこちらを参考にさせて頂きました
  • break については条件にマッチした場合にそれ以降の処理を rewrite 処理を行わない

引き続き

  • nginx の設定ってプログラムっぽくて面白い!