web-dev-qa-db-ja.com

Nginxリバースプロキシ+ URL書き換え

Nginxはポート80で実行されています。これを使用して、パス/fooからポート3200へのプロキシURLを次のようにリバースします。

location /foo {
                proxy_pass http://localhost:3200;
                proxy_redirect     off;
                proxy_set_header   Host $Host;
}

これは正常に動作しますが、ポート3200にアプリケーションがあり、最初の/fooを送信したくない場合があります。つまり、http://localhost/foo/barにアクセスするとき、/barだけをアプリが受け取ったパスにしたいと思います。だから私はこの行を上のロケーションブロックに追加してみました:

rewrite ^(.*)foo(.*)$ http://localhost:3200/$2 permanent;

これにより302リダイレクト(URLの変更)が発生しますが、301が必要です。どうすればよいですか?

172
jeffreyveon

Localhostへのリダイレクトは、リモートシステム(クライアントのWebブラウザなど)からは意味がありません。したがって、 rewrite flags パーマネント(301)またはリダイレクト(302)は、このケースでは使用できません。

透過的な書き換えルールを使用して次の設定を試してください:

location  /foo {
  rewrite /foo/(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     off;
  proxy_set_header   Host $Host;
}

使用する curl -i書き換えをテストします。ルールに微妙な変更を加えると、nginxがリダイレクトを実行する可能性があります。

188
Jens Bradler

Proxy_passディレクティブでURIを指定している限り、書き換えルールを使用しなくても、単純なロケーションプレフィックスマッチングが機能します。

location /foo {
  proxy_pass http://localhost:3200/;
}

/ディレクティブの最後にある追加のproxy_passに注意してください。 NGINXは一致した接頭辞/fooを取り除き、残りをURI /のバックエンドサーバーに渡します。したがって、http://myserver:80/foo/barhttp://localhost:3200/barのバックエンドに投稿します。

proxy_passのNGINXドキュメント から:

Proxy_passディレクティブがURIで指定されている場合、リクエストがサーバーに渡されると、正規化されたリクエストURIの場所に一致する部分が、ディレクティブで指定されたURIに置き換えられます。

146
DanArl

絶対的に最も正しい方法とベストプラクティスは、通常次のとおりです。

location /foo/ {
    proxy_pass http://localhost:3200/; # note the trailing slash!
}

  • proxy_pass変数を自動的に変更して、フロントエンドの$uriがバックエンドの/foo/に対応するように、末尾のスラッシュで/の重要性に注意してください。明示的なrewriteディレクティブは不要です。

  • さらに、locationの末尾の/も非常に重要であることに注意してください。これがないと、サイトのURLが変に見える可能性があります(例:/fooen in /foo/enに加えて)。

    さらに、/を使用したlocationの末尾のproxy_passも、locationディレクティブのドキュメントに従って、いくつかの特別な処理を保証し、暗黙のlocation = /foo {return 301 /foo/;}も効果的に引き起こします。

    したがって、上記のように末尾にスラッシュを付けてlocationを定義することで、/fooenのようなスラッシュのないサフィックスURLが無効になるだけでなく、末尾にスラッシュがない/fooも引き続き機能するようになります。


リファレンスドキュメント:

71
cnst

試す

location /foo {
    proxy_pass http://localhost:3200/;
    ....

または

location ^~ /foo {
    proxy_pass http://localhost:3200/;
    ....
2
DerGeh

@Terabuckまだ返信がないため申し訳ありません。

Localhostは、アプリケーションがホストファイルのあるサーバーで実行されているという事実に依存しているため、使用しないでください。ローカルホストは、127.0.0.1へのデフォルトの変換にすぎません。このhostsファイルが必要であることを示すものは何もありません。持っていることは非常に一般的です。

ループバックインターフェイスを持つことも、依存する別の一般的なことですが、ネットワークスタック上のループバックインターフェイスに依存しています。これら2つを持たないのはまれなケースです。あなたがこれについて心配するならば。少なくともunix/linuxでは、ソケットのオプションがあります。これにより、ネットワークスタックがローカルホストに到達する必要がなくなります。ホストOSにはいくつかの要因があるため、このアプローチには注意が必要です。開いているファイルの数など。

1
Cody Van Lith