http://example.com/
で実行中のWebアプリケーションがあり、http://example.com/en
上の別のサーバーに別のアプリケーションを「マウント」したいと考えています。アップストリームサーバーとproxy_pass
は機能しているようですが、1つの問題があります。
upstream luscious {
server lixxxx.members.linode.com:9001;
}
server {
root /var/www/example.com/current/public/;
server_name example.com;
location /en {
proxy_pass http://luscious;
}
}
example.com/en
を開くと、アップストリームアプリケーションが404 not found /en
を返します。アップストリームにはパス/en
がないため、これは理にかなっています。
proxy_path
は正しいソリューションですか?ルートパスとして代わりに/en
をリッスンするように、「アップストリーム」を書き換える必要がありますか?または、上流に渡されるパスを書き換えることができるディレクティブはありますか?
これは、正規表現を使用せずに、必要なことを行う最も効率的な方法です。
location = /en {
return 302 /en/;
}
location /en/ {
proxy_pass http://luscious/; # note the trailing slash here, it matters!
}
私は、人気が高まっている、より新しい正規表現ベースの回答に取り組みたいと思います。
_location ~ ^/en(/?)(.*)$ { # OOPS!
proxy_pass http://luscious/$2$is_args$args; # OOPS!
}
_
ソリューションは一見するとよりかわいく見えるかもしれませんが、いくつかの理由で間違っています。
上記の正規表現は_/enjoy
_のリクエストURIに一致し、それを_/joy
_アップストリームにリダイレクトします。これは本当に意図されているのですか?
_/en
_のリクエストはリダイレクトされず、上流から_/
_を直接提供します(代わりに_/en/
_のリクエストが行われたかのように、完全ではありません)。上流のルートページ内で相対URIを使用する場合(そうでない場合、上流のURI内に_/en/
_プレフィックスが付いていないのはなぜですか?)、たとえば_src="style.css"
_(たとえば、言語固有のurl("menu.png")
を参照する場合があります)の場合、ブラウザは_/style.css
_ではなく_/en/style.css
_として要求します。 (または、どこでも絶対URIを使用している場合でも、誰かがあいまいなセミオプションリソースを相対的に参照している場合はどうなりますか?).
私の OP自身の回答ですでに言及されている別の質問での以前のアドバイス のように、正規表現を使用すると _proxy_redirect
_ ディレクティブがdefault
、代わりにoff
に下げます。これは、_Location: http://127.0.0.1:8080/en/dir/
_の要求が行われたときにアップストリームが_/en/dir
_で応答した場合、クライアントがそれを表示し、明らかに正しく動作しないことを意味します。 (これは、最初に正規表現の使用を促す_/en
_要求に対して特に皮肉なことでしたが、この特定の実装は、前述のように別の問題に悩まされています。)さらに、すでに-を使用している場合 upstream
ディレクティブ。カスタムサーバーを使用しようとすると、特に複数の上流サーバーがある場合は、さらに醜くなる可能性があります。別の_proxy_redirect
_それらのそれぞれについて? _proxy_redirect
_内で正規表現を使用して、任意のホストに一致させることもできますが、将来的にクロスドメインリダイレクトを指定する場合はどうでしょうか。
単一の正規表現ベースの場所で上記のポイントのいくつかに対処するには、次のようにします(_proxy_pass
_では、upstream
からサーバーへの参照も削除する必要があることに注意してください)ベースのディレクティブ、_proxy_redirect
_をより簡単にするため):
_location ~ ^/en/?((?<=/).*)?$ {
location = /en { return 302 /en/; }
proxy_pass http://127.0.0.1:8080/$1$is_args$args;
proxy_redirect http://127.0.0.1:8080/ /en/;
}
_
したがって、私に尋ねると、 2つの兄弟の最上位の場所を含む元のソリューション は、代わりに正規表現のルートを使用してウサギの穴を掘り下げるよりも優れたアイデアです。
だから、私は stackoverflowの答え を見つけました:
upstream luscious {
server lixxxx.members.linode.com:9001;
}
server {
root /var/www/example.com/current/public/;
server_name example.com;
location ~ ^/en(/?)(.*) {
proxy_pass http://luscious/$2;
}
}
基本的に:正規表現を場所に渡し、backrefをproxy_pass URLに渡します。
会計 Nginxドキュメント
リクエストをHTTPプロキシサーバーに渡すには、場所内にproxy_passディレクティブを指定します。例えば:
location /some/path/ {
proxy_pass http://www.example.com/link/;
}
この構成例では、この場所で処理されたすべての要求を、指定されたアドレスのプロキシサーバーに渡します。このアドレスは、ドメイン名またはIPアドレスとして指定できます。アドレスにはポートが含まれる場合もあります。
location ~ \.php {
proxy_pass http://127.0.0.1:8000;
}
上記の最初の例では、プロキシされたサーバーのアドレスの後にURI/link /が続いていることに注意してください。 URIがアドレスとともに指定されている場合、それは、locationパラメーターと一致する要求URIの一部を置き換えます。たとえば、ここでは/some/path/page.html URIを含むリクエストは http://www.example.com/link/page.html にプロキシされます。 URIなしでアドレスが指定されている場合、または置き換えられるURIの部分を判別できない場合は、完全な要求URIが渡されます(おそらく変更されます)。