Nginxのproxy_passを書くときの注意点
proxy_pass
を設定する時に陥りやすい罠と注意事項を解説する。
作成日:2019-03-04
URIを指定する場合、しない場合
ドメイン以下の/
から始まる文字列をURIと呼ぶ。Nginxのproxy_pass
はURIの有無で挙動が変わる。そのため、次の2つの設定はそれぞれ別のアドレスへとプロキシされる。
# With URI
location /name/ {
proxy_pass http://127.0.0.1/; # / at end of line
}
# No URI
location /name/ {
proxy_pass http://127.0.0.1; # no / at end of line
}
proxy_pass
にURIを指定した場合、正規化されたリクエストURI[1]の一部がproxy_pass
のURIに置き換えられる。このとき、locationディレクティブで指定したURIが消去され、プロキシ先のURIが付与される。
例えば リクエストURLがhttp://example.com/name/index.html
だった場合、リクエストURIが/name/index.html
から
Request : http://example.com/name/index.html
Request URI : /name/index.html
Rewritten URI : /index.html
Proxied to : http://127.0.0.1/index.html
Proxied http://127.0.0.1/index.html`として転送される。
一方、URIを指定しなかった場合はURIの置換が行われず、http://example.com/name/index.html
へのリクエストはhttp://127.0.0.1/name/index.html
へ転送される。
どちらが正しいという話ではなく、状況に応じて使い分ける必要がある。
URIが置換されない他の条件
実はURIが置換されない条件は他にもある。
- When location is specified using a regular expression, and also inside named locations.
- When the URI is changed inside a proxied location using the rewrite directive, and this same configuration will be used to process a request (break):
- When variables are used in proxy_pass:
# use regex
location ~ /name/(.*) {
# proxied to http://127.0.0.1/name/$1
proxy_pass http://127.0.0.1;
}
# use named location
location @fallback {
# proxied to http://127.0.0.1/$uri
proxy_pass http://127.0.0.1;
}
# rewrite uri and break
location /name/ {
# proxied to http://127.0.0.1/$1
rewrite /name/(.*) $1 break;
proxy_pass http://127.0.0.1;
}
# use variable in proxy_pass
location /name/ {
# proxied to http://127.0.0.1/name/...
proxy_pass http://127.0.0.1$request_uri
}
どうするのが良いのか?
いろいろな考え方があるが、
- URIが正規化されても問題にならないようなら、末尾/でプロキシすると書き換えが簡単。
- URIの正規化を防ぐ場合、URIの書き換えを手動で行う。
公式ドキュメント
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
-
相対パスの解決、
?
以下のクエリの削除、エンコード文字のデコードなどが行われる。 ↩︎