Problem: Nginx-Fehler "Host Not Found In Upstream"
Der Fehler "Host Not Found In Upstream" in Nginx kann bei der Verwendung von Docker-Containern auftreten. Dieser Fehler tritt auf, wenn Nginx den Upstream-Server in seiner Konfiguration nicht auflösen oder keine Verbindung zu ihm herstellen kann. Er resultiert oft aus Netzwerkproblemen oder falschen Einstellungen in der Docker-Umgebung.
Lösung des Nginx-Fehlers "Host Not Found In Upstream"
Verwendung von depends_on in docker-compose.yml
Die Anweisung depends_on in docker-compose.yml hilft bei der Verwaltung der Startreihenfolge von Containern. Sie weist Docker an, bestimmte Container vor anderen zu starten. Dies kann dazu beitragen, den Fehler "Host Not Found In Upstream" zu verhindern, indem sichergestellt wird, dass die erforderlichen Dienste laufen, bevor Nginx startet.
Um depends_on in Ihrer docker-compose.yml-Datei zu implementieren, fügen Sie es unter dem Nginx-Dienst hinzu und listen Sie die Dienste auf, auf die gewartet werden soll:
version: '3'
services:
nginx:
image: nginx
depends_on:
- php
# Weitere Nginx-Konfiguration...
php:
image: php:fpm
# PHP-Konfiguration...
Tipp: Überprüfen Sie die Bereitschaft des Dienstes
Beachten Sie, dass depends_on nur darauf wartet, dass der Container startet, nicht darauf, dass der Dienst im Inneren vollständig bereit ist. Für komplexere Setups sollten Sie die Verwendung von Healthchecks oder wait-for-it-Skripten in Betracht ziehen, um sicherzustellen, dass Dienste vollständig funktionsfähig sind, bevor Nginx startet.
Aktualisierung der Nginx-Konfiguration
Überprüfen Sie die fastcgi_pass-Anweisung in Ihrer Nginx-Konfiguration. Stellen Sie sicher, dass sie den korrekten Dienstnamen verwendet, wie er in Ihrer docker-compose.yml-Datei definiert ist. Wenn Ihr PHP-Dienst in docker-compose.yml als "php" benannt ist, sollte Ihr fastcgi_pass so aussehen:
fastcgi_pass php:9000;
Überprüfen Sie auch, ob die Dienstnamen in Ihrer Nginx-Konfiguration mit denen in Ihrer docker-compose.yml-Datei übereinstimmen. Nicht übereinstimmende Namen können den Fehler "Host Not Found In Upstream" verursachen.
Implementierung von wait-for-it-Skripten
Wait-for-it-Skripte sind Shell-Skripte, die den Start eines Containers verzögern, bis ein bestimmter Dienst bereit ist. Diese Skripte können dazu beitragen, den Fehler "Host Not Found In Upstream" zu verhindern, indem sie sicherstellen, dass Nginx erst startet, nachdem die erforderlichen Dienste vollständig betriebsbereit sind.
Um ein wait-for-it-Skript in Ihrem Docker-Setup zu verwenden:
- Fügen Sie das Skript zu Ihrem Projektverzeichnis hinzu.
- Aktualisieren Sie Ihr Dockerfile, um das Skript einzubinden.
- Ändern Sie den Befehl in Ihrer docker-compose.yml, um das wait-for-it-Skript zu verwenden:
nginx:
image: nginx
depends_on:
- php
command: ["./wait-for-it.sh", "php:9000", "--", "nginx", "-g", "daemon off;"]
# Weitere Nginx-Konfiguration...
Dieser Ansatz bietet zusätzlichen Schutz vor Timing-Problemen, die den Fehler "Host Not Found In Upstream" verursachen können.
Beispiel: Benutzerdefiniertes Wait-Skript
Sie können ein benutzerdefiniertes Wait-Skript erstellen, das auf Ihre spezifischen Bedürfnisse zugeschnitten ist. Hier ist ein einfaches Beispiel in Bash:
#!/bin/bash
set -e
host="$1"
shift
cmd="$@"
until nc -z "$host" 9000; do
>&2 echo "PHP-FPM ist nicht verfügbar - warte"
sleep 1
done
>&2 echo "PHP-FPM ist bereit - führe Befehl aus"
exec $cmd
Speichern Sie dies als wait-for-php.sh in Ihrem Projektverzeichnis, machen Sie es ausführbar und aktualisieren Sie Ihre docker-compose.yml, um es zu verwenden:
nginx:
image: nginx
depends_on:
- php
command: ["./wait-for-php.sh", "php", "nginx", "-g", "daemon off;"]
# Weitere Nginx-Konfiguration...
Alternative Lösungen zur Behebung des Nginx-Fehlers
Verwendung von Docker-Netzwerken
Die Erstellung von benutzerdefinierten Docker-Netzwerken kann helfen, den Fehler "Host Not Found In Upstream" zu beheben. Benutzerdefinierte Netzwerke ermöglichen es Containern, unter Verwendung ihrer Dienstnamen als Hostnamen zu kommunizieren.
Um ein benutzerdefiniertes Netzwerk zu erstellen:
- Definieren Sie das Netzwerk in Ihrer docker-compose.yml-Datei:
networks:
myapp_network:
driver: bridge
- Verbinden Sie Ihre Dienste mit diesem Netzwerk:
services:
nginx:
image: nginx
networks:
- myapp_network
php:
image: php:fpm
networks:
- myapp_network
Durch die Verwendung eines benutzerdefinierten Netzwerks verbessern Sie die Container-Kommunikation und reduzieren Probleme bei der Hostnamenauflösung.
Tipp: Netzwerk-Isolation
Erstellen Sie separate Netzwerke für verschiedene Teile Ihrer Anwendung, um die Sicherheit zu verbessern und den Datenverkehr zu steuern. Sie können beispielsweise ein Frontend-Netzwerk für Webserver und ein Backend-Netzwerk für Datenbanken haben:
networks:
frontend:
driver: bridge
backend:
driver: bridge
services:
nginx:
networks:
- frontend
php:
networks:
- frontend
- backend
database:
networks:
- backend
Implementierung von Healthchecks
Healthchecks in docker-compose.yml können den Fehler "Host Not Found In Upstream" verhindern, indem sie sicherstellen, dass ein Dienst bereit ist, bevor andere Dienste, die davon abhängen, gestartet werden.
Um Healthchecks hinzuzufügen:
- Fügen Sie einen Healthcheck in Ihrer docker-compose.yml für den PHP-Dienst hinzu:
services:
php:
image: php:fpm
healthcheck:
test: ["CMD", "php-fpm", "-t"]
interval: 10s
timeout: 5s
retries: 3
- Aktualisieren Sie den Nginx-Dienst, um von der Gesundheit des PHP-Dienstes abhängig zu sein:
services:
nginx:
image: nginx
depends_on:
php:
condition: service_healthy
Diese Konfiguration stellt sicher, dass Nginx erst startet, nachdem der PHP-Dienst bereit ist, Verbindungen anzunehmen, was die Wahrscheinlichkeit des Fehlers "Host Not Found In Upstream" reduziert.