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