はじめに
- 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 の末尾に ?
を付けるだけ。
デモ
?
無し。
以下のように設定して...
rewrite ^(.*)$ http://172.17.0.3:8000/maintenance.html permanent;
アクセスすると...
見事にパラメータ(?hoge
)が引き継がれている。
?
有り。
以下のようにして...
rewrite ^(.*)$ http://172.17.0.3:8000/maintenance.html? permanent;
アクセスすると...
見事にパラメータが無くなっている。
参考(※追記)
ちなみにドキュメントに以下のように記載されていた。
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_addr
がxxx.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; } }
デモ
break
をコメントアウトして...
if ($remote_addr ~ ^172\.17\.42\.1$) { # break; }
/etc/init.d/nginx restart
する。
見事にメンテナンスページに飛ばされた。
そして、break
を有効にする。
if ($remote_addr ~ ^172\.17\.42\.1$) { break; }
そして、/etc/init.d/nginx restart
する。
メンテナンスページにはリダイレクトされずに通常のページが表示される。
メモ
引き続き
- nginx の設定ってプログラムっぽくて面白い!