So entfernen Sie den Pfad mit einem Nginx-Proxy-Pass

So entfernen Sie den Pfad mit einem Nginx-Proxy-Pass

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_passscheinen 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/engibt meine Upstream-Anwendung zurück 404 not found /en. Das ist sinnvoll, da der Upstream den Pfad nicht hat /en.

Ist proxy_pathdas die richtige Lösung? Sollte ich „Upstream“ umschreiben, damit es /enstattdessen 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 /enjoyweiterleiten . Ist das wirklich beabsichtigt?/joy

  • Eine Anforderung für /enfü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?), zB src="style.css"(das beispielsweise auf ein sprachspezifisches verweisen könnte url("menu.png")), dann fordert der Browser das als /style.cssanstelle 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 dieproxy_redirect-Direktive vom Standardwert auf defaultabzusetzen und ihn offstattdessen 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/dirgestellt wird, dies das ist, was der Client sieht, was offensichtlich nicht richtig funktioniert. (Was besonders ironisch gewesen wäre für eine /enAnfrage, 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 dieupstreamDirektive, 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 Sie proxy_redirectfür jeden davon einen eigenen haben? Sie könnten proxy_redirectauch 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_passlöschen mussten ):upstreamproxy_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;
}

verwandte Informationen