Wir haben mehrere Rails-Apps unter einer gemeinsamen Domäne in Docker und verwenden Nginx, um Anfragen an bestimmte Apps zu leiten.
our_dev_server.com/foo # proxies to foo app
our_dev_server.com/bar # proxies to bar
Die Konfiguration sieht folgendermaßen aus:
upstream foo {
server foo:3000;
}
upstream bar {
server bar:3000;
}
# and about 10 more...
server {
listen *:80 default_server;
server_name our_dev_server.com;
location /foo {
# this is specific to asset management in rails dev
rewrite ^/foo/assets(/.*)$ /assets/$1 break;
rewrite ^/foo(/.*)$ /foo/$1 break;
proxy_pass http://foo;
}
location /bar {
rewrite ^/bar/assets(/.*)$ /assets/$1 break;
rewrite ^/bar(/.*)$ /bar/$1 break;
proxy_pass http://bar;
}
# and about 10 more...
}
Wenn eine dieser Apps nicht gestartet wird, schlägt nginx fehl und stoppt:
host not found in upstream "bar:3000" in /etc/nginx/conf.d/nginx.conf:6
Wir brauchen nicht alle, um auf zu sein, aber Nginx schlägt sonst fehl. Wie kann man Nginx dazu bringen, fehlgeschlagene Upstreams zu ignorieren?
nginx
url-rewriting
proxypass
Morozov
quelle
quelle
upstream
Blocks zur Laufzeit nicht aufgelöst wird, wird Nginx mit dem obigen Fehler beendet ...resolver
( nginx.org/en/docs/http/ngx_http_core_module.html#resolver ) in Ihrem Fall funktionieren?proxy.sh
Skript enthält, das Umgebungsvariablen liest undupstream
für jedes dynamisch Einträge hinzufügt . Anschließend wird Nginx gestartet. Dies funktioniert insofern hervorragend, als wir beim Ausführen unseres Proxy-Containers zur Laufzeit die erforderlichen Upstreams übergeben können. Sie könnten etwas Ähnliches tun, um bestimmte Upstreams beim Start zu aktivieren / deaktivieren (oder wie mein Setup nur die zur Laufzeit benötigten hinzufügen)Antworten:
Wenn Sie eine statische IP verwenden können, verwenden Sie diese einfach. Sie wird gestartet und gibt nur dann zurück
503
, wenn sie nicht antwortet.Verwenden Sie die
resolver
Anweisung, um auf etwas zu verweisen, das den Host auflösen kann, unabhängig davon, ob er gerade aktiv ist oder nicht.Löse es auf der
location
Ebene, wenn du das oben genannte nicht kannst (dies ermöglicht es Nginx zu starten / laufen zu lassen) :quelle
location ~ ^/foo/(.*)$ { proxy_pass http://foo/$1; }
Für mich löste Option 3 der Antwort von @ Justin / @ duskwuff das Problem, aber ich musste die Resolver-IP auf ändern 127.0.0.11 (Docker-DNS-Server) :
Aber wie @ Justin / @ duskwuff erwähnt, können Sie jeden anderen externen DNS-Server verwenden.
quelle
Der Hauptvorteil der Verwendung
upstream
besteht darin, eine Gruppe von Servern zu definieren, die verschiedene Ports überwachen und den Lastenausgleich und das Failover zwischen ihnen konfigurieren können .In Ihrem Fall definieren Sie nur 1 Primärserver pro Upstream, sodass dieser aktiv sein muss .
Verwenden Sie stattdessen Variablen für Ihre
proxy_pass
(n) und denken Sie daran, die möglichen Fehler (404s, 503s) zu behandeln, die auftreten können, wenn ein Zielserver ausfällt.quelle
set $variable http://foo
undproxy_pass $variable
halte (um die von Ihnen erwähnten Vorteile zu erhalten), treffe ich immer noch das von OP erwähnte Problem.set $variable foo
undproxy_pass http://$variable
Ich hatte das gleiche Problem "Host nicht gefunden", da ein Teil meines Hosts mithilfe
$uri
von$request_uri
:Und als die Anforderung in die Auth-Unteranforderung geändert wurde,
$uri
verlor die ihren Anfangswert. Das Ändern des zu verwendenden Mappings$request_uri
anstelle$uri
meines Problems hat mein Problem gelöst:quelle
Sie können nicht verwenden
--link
Option , stattdessen können Sie die Portzuordnung verwenden und nginx an die Hostadresse binden.Beispiel: Führen Sie Ihren ersten Docker-Container mit
-p 180:80
Option und den zweiten Container mit aus-p 280:80
Option aus.Führen Sie nginx aus und legen Sie diese Adressen für den Proxy fest:
quelle