Ich habe eine laufende Webanwendung unter http://example.com/
und möchte eine andere Anwendung auf einem separaten Server unter „mounten“ http://example.com/en
. Upstream-Server und proxy_pass
scheinen zu funktionieren, aber es gibt ein Problem:
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;
}
}
Beim Öffnen example.com/en
gibt meine Upstream-Anwendung zurück 404 not found /en
. Das ist sinnvoll, da der Upstream den Pfad nicht hat /en
.
Ist proxy_path
das die richtige Lösung? Sollte ich „Upstream“ umschreiben, damit es /en
stattdessen auf seinen Stammpfad hört? Oder gibt es eine Anweisung, mit der ich den an Upstream weitergegebenen Pfad umschreiben kann?
Antwort1
Dies ist wahrscheinlich die effizienteste Möglichkeit, Ihr Ziel zu erreichen, ohne reguläre Ausdrücke zu verwenden:
location = /en {
return 302 /en/;
}
location /en/ {
proxy_pass http://luscious/; # note the trailing slash here, it matters!
}
Antwort2
Ich möchte auf eine neuere, auf regulären Ausdrücken basierende Antwort eingehen, die immer beliebter wird.
location ~ ^/en(/?)(.*)$ { # OOPS!
proxy_pass http://luscious/$2$is_args$args; # OOPS!
}
Die Lösung mag auf den ersten Blick niedlicher erscheinen, ist aber aus mehreren Gründen falsch.
Der obige reguläre Ausdruck würde mit einer Anforderungs-URI von übereinstimmen und diese an Upstream
/enjoy
weiterleiten . Ist das wirklich beabsichtigt?/joy
Eine Anforderung für
/en
führt zu keinen Weiterleitungen, sondern liefert direkt ein/
vom Upstream (fast so, als ob/en/
stattdessen eine Anforderung für gestellt worden wäre, aber nicht ganz). Wenn Sie relative URIs innerhalb Ihrer Stammseite Upstream verwenden (warum hätten Sie sonst das/en/
Präfix nicht direkt innerhalb der Upstream-URIs?), zBsrc="style.css"
(das beispielsweise auf ein sprachspezifisches verweisen könnteurl("menu.png")
), dann fordert der Browser das als/style.css
anstelle von an/en/style.css
. (Oder selbst wenn Sie überall absolute URIs verwenden, was ist, wenn jemand relativ auf eine obskure, halboptionale Ressource verweist?) Ups, plötzlich funktioniert die Site möglicherweise nicht mehr, aber nur manchmal oder in Randfällen.Gemäß meinerfrüherer Rat zu einer anderen Frage, die bereits in der Antwort des OP erwähnt wurde, die Verwendung von regulären Ausdrücken verhindert die
proxy_redirect
-Direktive vom Standardwert aufdefault
abzusetzen und ihnoff
stattdessen auf zu ändern. Das bedeutet, dass, wenn der Upstream mit antwortet,Location: http://127.0.0.1:8080/en/dir/
wenn eine Anfrage für/en/dir
gestellt wird, dies das ist, was der Client sieht, was offensichtlich nicht richtig funktioniert. (Was besonders ironisch gewesen wäre für eine/en
Anfrage, die überhaupt erst die Verwendung von regulären Ausdrücken fordert, aber diese spezielle Implementierung leidet stattdessen unter einem anderen Problem, wie bereits oben erwähnt.) Außerdem, wenn Sie bereits dieupstream
Direktive, dann könnte es besonders hässlich werden, wenn Sie einfach versuchen, eine benutzerdefinierte zu verwenden, insbesondere wenn Sie möglicherweise mehr als einen Upstream-Server haben – wie können Sieproxy_redirect
für jeden davon einen eigenen haben? Sie könntenproxy_redirect
auch reguläre Ausdrücke darin verwenden, vielleicht sogar, um jeden Host abzugleichen, aber was ist, wenn Sie sich in Zukunft für eine domänenübergreifende Umleitung entscheiden?
Um zu versuchen, einige der oben genannten Punkte mit einem einzigen auf regulären Ausdrücken basierenden Standort zu behandeln, könnten wir Folgendes tun (beachten Sie, dass wir zur Vereinfachung auch den Verweis auf einen Server aus einer -basierten Direktive proxy_pass
löschen mussten ):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/;
}
Wenn Sie mich also fragen,Originallösung mit den beiden Schwesterstandorten auf oberster Ebenewäre immer noch eine bessere Idee, als sich durch den Einsatz des Regex-Weges in ein Kaninchenloch zu graben.
Antwort3
Ich fand also dieAntwort auf 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;
}
}
Grundsätzlich gilt: Übergeben eines regulären Ausdrucks an den Standort und Übergeben des Backref an die Proxy-Pass-URL.
Antwort4
Ich habe mit der oben akzeptierten Lösung herumgespielt, aber festgestellt, dass sie zu fragwürdigen Weiterleitungen für alle CSS- und JS-Assets führte. Am Ende ließ ich mich von der Art und Weise inspirieren, wie die LinuxServer SWAG Nginx-Konfigurationen vorgenommen werden. Sie finden sieHier. Schauen Sie sich an pihole.subfolder.conf.sample
.
Meine Lösung sieht daher folgendermaßen aus:
location /en {
return 302 $scheme://$host/en/;
}
location ^~ /en/ {
set $upstream_app lixxxx.members.linode.com;
set $upstream_port 9001;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
rewrite /en(.*) $1 break;
}