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
}

どうするのが良いのか?

いろいろな考え方があるが、

公式ドキュメント

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass


  1. 相対パスの解決、?以下のクエリの削除、エンコード文字のデコードなどが行われる。 ↩︎