d:id:sfujiwara:20100812:1281587030 の revise。
Nginxのifは条件節に&&(and)が使えない、ifのネストもできないので、複数の条件で判別したい場合は変数を使うといいよって感じです。
server {
...
#error_page 500 502 503 504 /static/50x.html;
### maintenance
error_page 500 502 504 /static/50x.html;
set $go_maintenance "true";
if ($uri ~ "^/error/") {
set $go_maintenance "false";
}
if ($remote_addr ~ "^192\.0\.2\.") {
set $go_maintenance "false";
}
if ($remote_addr ~ "^10\.0\.0\.") {
set $go_maintenance "false";
}
if ($http_user_agent ~ "nakanohito-desu") {
set $go_maintenance "false";
}
if ($http_x_open = "sesame!") {
set $go_maintenance "false";
}
error_page 503 /error/503.html;
location /error/ {}
if ($go_maintenance = "true") { return 503; } # maintenance
### /maintenance
location /static {
alias /usr/irori/contents/example.com/static;
expires 1h;
gzip on;
gzip_types text/css application/javascript application/x-javascript;
keepalive_timeout 3 3;
}
location / {
proxy_pass http://127.0.0.1:2006;
...
}
location ... {
...
}
}
- ミソは「### maintenance」から「### /maintenance」まで。
- カスタムのメンテページを出したい && 既存の設定(error_page)で503の制御をしている場合はコメントアウトして503だけはカスタムのメンテページを表示するようにする。
- カスタムメンテページは /error/ 下に配置する。メンテページで画像とか使う場合もこのディレクトリ配下に置く。
- 既存設定のlocationに食われないように、location /error/ {}と設定しておく。
- 503にするかどうかは変数$go_maintenanceで判断する。初期値は"true"。(メンテ前は"false"にしておけばよろし)
- カスタムメンテページは503になっちゃまずいので、^/error/ は "false"
- ほか、メンテ中に中の人が動作確認したい条件をひっかけて "false" にする
- $remote_addr でアクセス元のIPアドレスとか
- $remote_addrをたくさん羅列したい場合は、HttpGeoModuleを使った方が効率的。
- $http_user_agent でUser-Agentヘッダとか
- $http_x_open とかでカスタムのHTTPリクエストヘッダとか
- $remote_addr でアクセス元のIPアドレスとか
- で、if ($go_maintenance = "true") { return 503; }
- server {}の中でreturn 503してるので、後続にlocationブロックがたくさんあってもこれだけでOK