Nginx Virtual Hosts: Mehrere Websites auf einem Server hosten
Nutzen Sie die Leistungsfähigkeit von Nginx Virtual Hosts (Server-Blöcke), um effizient mehrere Websites oder Subdomains auf einem einzelnen Server zu hosten. Diese Anleitung bietet ein umfassendes, schrittweises Tutorial, das die Einrichtung von Verzeichnissen, die Erstellung von Konfigurationsdateien, das Aktivieren von Server-Blöcken und das Testen von Nginx abdeckt. Lernen Sie Best Practices für Subdomains, Standard-Server-Blöcke, HTTPS-Integration und dediziertes Logging kennen. Praktische Beispiele und wichtige Tipps zur Fehlerbehebung helfen Ihnen, das Multi-Site-Hosting mit Nginx zu meistern, die Ressourcennutzung zu optimieren und die Verwaltung des Webservers zu optimieren.
Nginx Virtual Hosts: Mehrere Websites auf einem Server hosten
Mehrere kleine Seiten von einem Server aus zu betreiben, ist eine normale Nginx-Aufgabe. Sie haben vielleicht eine Unternehmensseite, eine Dokumentationsseite, eine Staging-App und ein Kundenportal, die alle auf derselben Maschine landen. Nginx trennt sie mit server-Blöcken. Apache-Entwickler nennen dieselbe Idee oft Virtual Hosts, daher werden Sie beide Begriffe in Tutorials und Hosting-Panels sehen.
Der wichtige Teil ist einfach: Nginx betrachtet den Port, die IP-Adresse und den Host-Header und wählt dann den passenden server-Block aus. Wenn die falsche Seite geladen wird, ist das Problem normalerweise nicht mysteriös. Oft liegt es an einem fehlenden DNS-Eintrag, einem Tippfehler in server_name, einem Standard-Server, der die Anfrage abfängt, oder zwei Dateien, die denselben Namen beanspruchen.
Nginx Server-Blöcke (Virtual Hosts) verstehen
Im Kern ist ein Nginx Server-Block eine Konfigurationsdirektive, die innerhalb der Nginx-Konfigurationsdatei (nginx.conf oder eingebundenen Dateien) definiert wird. Jeder server-Block definiert die Konfiguration für einen bestimmten virtuellen Host und legt fest, wie Nginx auf Anfragen für eine bestimmte Domain oder eine Gruppe von Domains reagieren soll. Nginx verwendet die listen-Direktive, um die IP-Adresse und den Port anzugeben, auf dem es lauschen soll, und die server_name-Direktive, um zu identifizieren, auf welche Domainnamen oder Hostnamen dieser Server-Block antworten soll.
Wenn eine Anfrage eingeht, untersucht Nginx den Host-Header der HTTP-Anfrage und vergleicht ihn mit den server_name-Direktiven seiner konfigurierten Server-Blöcke. Dann wird der Inhalt aus dem passenden Server-Block ausgeliefert. Wenn kein server_name übereinstimmt, fällt Nginx normalerweise auf den Standard-Server-Block zurück (den ersten server-Block oder einen, der explizit als default_server markiert ist).
Voraussetzungen
Bevor Sie beginnen, stellen Sie sicher, dass Folgendes vorhanden ist:
- Nginx installiert: Nginx sollte auf Ihrem Server installiert und ausgeführt werden. Falls nicht, können Sie es in der Regel über den Paketmanager Ihres Systems installieren (z. B.
sudo apt update && sudo apt install nginxunter Ubuntu/Debian,sudo yum install nginxunter CentOS/RHEL). - Domainnamen: Sie benötigen mindestens zwei Domainnamen (z. B.
example1.comundexample2.com) oder Subdomains (z. B.blog.example.comundapp.example.com), die Sie hosten möchten. Die DNS-A/AAAA-Einträge dieser Domains müssen auf die öffentliche IP-Adresse Ihres Servers zeigen. - Grundlegende Verzeichnisstruktur: Ein Plan, wo Ihre Website-Dateien abgelegt werden sollen. Eine gängige Praxis ist
/var/www/ihredomain.com/html. - Sudo-Rechte: Sie benötigen
sudo-Zugriff, um Nginx-Konfigurationsdateien zu ändern.
Schritt-für-Schritt-Einrichtungsanleitung
Richten wir zwei virtuelle Hosts ein: example1.com und example2.com.
Schritt 1: Verzeichnisstruktur für Websites erstellen
Erstellen Sie zunächst Stammverzeichnisse für jede Ihrer Websites. Hier werden ihre HTML-, CSS-, JavaScript- und anderen statischen Dateien gespeichert. Ein üblicher Ort ist /var/www/.
sudo mkdir -p /var/www/example1.com/html
sudo mkdir -p /var/www/example2.com/html
# Besitzer auf Ihren Benutzer setzen ($USER durch Ihren Benutzernamen ersetzen), um Bearbeitung zu ermöglichen
sudo chown -R $USER:$USER /var/www/example1.com/html
sudo chown -R $USER:$USER /var/www/example2.com/html
# Leseberechtigungen für den Webserver setzen
sudo chmod -R 755 /var/www
Erstellen Sie als Nächstes eine einfache index.html-Datei in jedem Verzeichnis, um die Einrichtung zu testen:
Für /var/www/example1.com/html/index.html:
<!-- /var/www/example1.com/html/index.html -->
<!DOCTYPE html>
<html>
<head>
<title>Willkommen bei Example1.com!</title>
</head>
<body>
<h1>Erfolg! Dies ist Example1.com.</h1>
<p>Dieser virtuelle Host funktioniert korrekt.</p>
</body>
</html>
Für /var/www/example2.com/html/index.html:
<!-- /var/www/example2.com/html/index.html -->
<!DOCTYPE html>
<html>
<head>
<title>Willkommen bei Example2.com!</title>
</head>
<body>
<h1>Erfolg! Dies ist Example2.com.</h1>
<p>Dieser virtuelle Host funktioniert auch!</p>
</body>
</html>
Schritt 2: Nginx Server-Block-Konfigurationsdateien erstellen
Nginx lädt Server-Block-Konfigurationen normalerweise aus Dateien im Verzeichnis /etc/nginx/sites-enabled/. Diese Dateien sind in der Regel symbolische Links auf Konfigurationen, die in /etc/nginx/sites-available/ gespeichert sind. Diese Trennung ermöglicht es Ihnen, Konfigurationen zu speichern, die noch nicht aktiv sind, oder Seiten einfach zu aktivieren/deaktivieren.
Erstellen Sie eine neue Konfigurationsdatei für example1.com:
sudo nano /etc/nginx/sites-available/example1.com.conf
Fügen Sie den folgenden Inhalt hinzu:
# /etc/nginx/sites-available/example1.com.conf
server {
listen 80;
listen [::]:80;
root /var/www/example1.com/html;
index index.html index.htm index.nginx-debian.html;
server_name example1.com www.example1.com;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/example1.com_access.log;
error_log /var/log/nginx/example1.com_error.log;
}
Erklärung der Direktiven:
listen 80;: Nginx lauscht auf Port 80 (Standard-HTTP).listen [::]:80;ist für IPv6.root /var/www/example1.com/html;: Gibt das Dokumentenwurzelverzeichnis für diesen Server-Block an. Nginx sucht in diesem Verzeichnis nach Dateien.index index.html ...;: Definiert die Standarddatei, die Nginx ausliefern soll, wenn ein Verzeichnis angefordert wird (z. B. wenn jemandexample1.com/besucht).server_name example1.com www.example1.com;: Dies ist entscheidend. Es teilt Nginx mit, auf Anfragen fürexample1.comoderwww.example1.commit der Konfiguration dieses Server-Blocks zu antworten.location / { ... }: Ein Block, der definiert, wie Anfragen für bestimmte URIs behandelt werden.try_filesversucht, eine Datei direkt ($uri), dann ein Verzeichnis ($uri/) auszuliefern und gibt schließlich einen404 Not Found-Fehler zurück.access_logunderror_log: Gibt separate Logdateien für diese spezifische Seite an, was eine gute Praxis für einfachere Fehlerbehebung und Analyse ist.
Erstellen Sie nun eine ähnliche Konfigurationsdatei für example2.com:
sudo nano /etc/nginx/sites-available/example2.com.conf
Fügen Sie den folgenden Inhalt hinzu:
# /etc/nginx/sites-available/example2.com.conf
server {
listen 80;
listen [::]:80;
root /var/www/example2.com/html;
index index.html index.htm index.nginx-debian.html;
server_name example2.com www.example2.com;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/example2.com_access.log;
error_log /var/log/nginx/example2.com_error.log;
}
Schritt 3: Server-Blöcke aktivieren
Um diese Konfigurationen zu aktivieren, erstellen Sie symbolische Links vom Verzeichnis sites-available in das Verzeichnis sites-enabled. Dies teilt Nginx mit, diese Dateien beim Start einzubinden.
sudo ln -s /etc/nginx/sites-available/example1.com.conf /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/example2.com.conf /etc/nginx/sites-enabled/
Schritt 4: Nginx-Konfiguration testen
Es ist entscheidend, Ihre Nginx-Konfiguration vor dem Neuladen auf Syntaxfehler zu testen. Dies verhindert, dass Nginx aufgrund eines Tippfehlers nicht neu startet.
sudo nginx -t
Sie sollten eine Ausgabe ähnlich der folgenden sehen, die den Erfolg anzeigt:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Wenn Sie Fehler sehen, korrigieren Sie diese in den entsprechenden Konfigurationsdateien und führen Sie sudo nginx -t erneut aus, bis es erfolgreich ist.
Schritt 5: Nginx neu starten
Wenden Sie die neue Konfiguration an, indem Sie Nginx neu starten oder neu laden. reload wird im Allgemeinen bevorzugt, da es Nginx ermöglicht, neue Konfigurationen zu laden, ohne aktive Verbindungen zu trennen.
sudo systemctl reload nginx
# Oder, falls reload nicht funktioniert oder bei Neuinstallationen:
sudo systemctl restart nginx
Schritt 6: DNS-Einträge aktualisieren
Stellen Sie sicher, dass die DNS-A-Einträge für example1.com, www.example1.com, example2.com und www.example2.com alle auf die IP-Adresse Ihres Nginx-Servers zeigen. Ohne korrekte DNS-Einträge weiß Ihr Browser nicht, wo er Ihre Websites finden soll.
Sobald die DNS-Propagation abgeschlossen ist (was einige Minuten bis mehrere Stunden dauern kann), sollten Sie in Ihrem Webbrowser http://example1.com und http://example2.com aufrufen und die entsprechenden index.html-Seiten sehen können.
Erweiterte Szenarien und Best Practices
Subdomains hosten
Das Hosten von Subdomains (z. B. blog.example.com, shop.example.com) funktioniert genauso wie das Hosten separater Domains. Sie definieren einfach einen neuen Server-Block mit der Subdomain als server_name.
Beispiel für blog.example.com:
# /etc/nginx/sites-available/blog.example.com.conf
server {
listen 80;
listen [::]:80;
root /var/www/blog.example.com/html;
index index.html;
server_name blog.example.com;
location / {
try_files $uri $uri/ =404;
}
}
Denken Sie daran, das Verzeichnis (/var/www/blog.example.com/html) zu erstellen, eine index.html zu erstellen, den symbolischen Link zu erstellen und Nginx neu zu laden.
Der Standard-Server-Block
Es ist gute Praxis, einen Standard-Server-Block zu haben, der Anfragen für Domainnamen abfängt, die mit keiner anderen server_name-Direktive auf Ihrem Server übereinstimmen. Dies verhindert, dass unbekannte Anfragen vom "ersten" virtuellen Host bedient werden, den Nginx findet, oder ermöglicht es Ihnen, eine generische "Seite nicht gefunden"-Seite auszuliefern.
Typischerweise ist der erste server-Block in Ihrer nginx.conf oder sites-enabled implizit der Standard. Sie können einen explizit mit default_server festlegen:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# Der Unterstrich `_` ist ein nicht existierender Domainname, der niemals mit einer echten Anfrage übereinstimmt.
# Sie können auch localhost verwenden.
root /var/www/default_site/html;
index index.html;
location / {
return 444; # Gibt einen Nginx-spezifischen 444-Fehler (keine Antwort) für unbekannte Hosts zurück
# Oder, liefern Sie eine generische Landingpage:
# try_files $uri $uri/ =404;
}
}
Warnung: Wenn Sie einen default_server-Block definieren, stellen Sie sicher, dass nur ein server-Block auf einem bestimmten listen-Port das default_server-Flag hat, da Nginx sonst eine Warnung protokolliert.
Virtuelle Hosts mit HTTPS (SSL/TLS) absichern
Für Produktionswebsites ist die Aktivierung von HTTPS unerlässlich. Dies beinhaltet das Einholen eines SSL/TLS-Zertifikats (z. B. über Let's Encrypt mit Certbot) und die Konfiguration von Nginx, um auf Port 443 mit dem Zertifikat zu lauschen.
Ein typischer HTTPS-Server-Block sieht so aus (nachdem Zertifikate eingeholt wurden):
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example1.com www.example1.com;
root /var/www/example1.com/html;
index index.html;
ssl_certificate /etc/letsencrypt/live/example1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example1.com/privkey.pem;
# Andere SSL-Konfigurationen einfügen (Chiffren, Protokolle usw.)
include /etc/nginx/snippets/ssl-params.conf;
location / {
try_files $uri $uri/ =404;
}
}
# Optional: HTTP-zu-HTTPS-Weiterleitung für diese Domain
server {
listen 80;
listen [::]:80;
server_name example1.com www.example1.com;
return 301 https://$host$request_uri;
}
Es ist üblich, einen separaten HTTP-Server-Block zu haben, dessen einziger Zweck es ist, den gesamten Traffic auf sein HTTPS-Gegenstück umzuleiten.
Wenn Sie Certbot verwenden, erstellt oder bearbeitet es möglicherweise diese Blöcke für Sie. Das ist praktisch, aber Sie sollten die resultierende Datei trotzdem lesen. Automatisierte Zertifikatstools fügen manchmal Weiterleitungslogik an einer Stelle hinzu, die Sie selbst nicht gewählt hätten, und doppelte Weiterleitungen können die Fehlerbehebung erschweren.
Logging für jede Seite
Wie in den Beispielen gezeigt, ist die Verwendung separater access_log- und error_log-Dateien für jeden virtuellen Host eine bewährte Methode. Dies erleichtert das Debuggen von Problemen und die Analyse des Datenverkehrs für einzelne Websites erheblich, ohne kombinierte Logs durchsuchen zu müssen.
Struktur der Konfigurationsdateien
Für größere Bereitstellungen sollten Sie Ihre Nginx-Konfigurationsdateien wie folgt organisieren:
nginx.conf: Hauptkonfiguration, bindetconf.d/*.confundsites-enabled/*ein.conf.d/: Allgemeine serverweite Einstellungen (z. B. Gzip, Caching).snippets/: Wiederverwendbare Nginx-Konfigurationsschnipsel (z. B. SSL-Parameter, gemeinsamelocation-Blöcke).sites-available/: Einzelneserver-Blöcke für jede Website.sites-enabled/: Symbolische Links zu aktiven Konfigurationen insites-available/.
Fehlerbehebung bei häufigen Problemen
- 403 Forbidden Error: Dies bedeutet normalerweise, dass Nginx keinen Lesezugriff auf die Dateien oder Verzeichnisse Ihrer Website hat. Überprüfen Sie die Datei- und Verzeichnisberechtigungen (z. B.
sudo chmod -R 755 /var/www/ihredomain.com/htmlund stellen Sie sicher, dass der Nginx-Benutzer, normalerweisewww-dataodernginx, sie lesen kann). - 404 Not Found Error: Überprüfen Sie, ob die
root-Direktive in Ihrem Server-Block auf das richtige Verzeichnis zeigt und ob Ihreindex.html-Datei an diesem Ort vorhanden ist. Stellen Sie außerdem sicher, dasstry_fileskorrekt konfiguriert ist. - Falsche Seite wird geladen: Dies deutet oft auf ein Problem mit der
server_name-Direktive hin. Stellen Sie sicher, dass derserver_namegenau mit dem Domainnamen übereinstimmt, den Sie aufrufen möchten (einschließlichwww.oder Subdomains). Überprüfen Sie auch Ihre DNS-Einträge. - Nginx startet/lädt nicht neu: Verwenden Sie immer
sudo nginx -t, um Ihre Konfiguration zu testen, bevor Sie versuchen, Nginx neu zu laden oder neu zu starten. Fehlermeldungen zeigen die Zeile und Datei an, in der der Syntaxfehler aufgetreten ist. - DNS-Probleme: Wenn Sie Ihre Seite über die IP-Adresse, aber nicht über den Domainnamen erreichen können, liegt es fast sicher an einem DNS-Problem. Verwenden Sie
digodernslookup, um zu überprüfen, ob die A-Einträge Ihrer Domain auf die richtige Server-IP zeigen.
Testen, bevor DNS bereit ist
Sie müssen nicht auf das öffentliche DNS warten, um die Nginx-Seite zu testen. Sie können eine Anfrage mit einem benutzerdefinierten Host-Header senden:
curl -H "Host: example1.com" http://203.0.113.10/
curl -H "Host: example2.com" http://203.0.113.10/
Ersetzen Sie 203.0.113.10 durch Ihre Server-IP. Wenn jeder Befehl die richtige Testseite zurückgibt, funktioniert der Server-Block-Matching. Wenn beide Befehle dieselbe Seite zurückgeben, überprüfen Sie, ob beide Dateien aktiviert sind, ob server_name korrekt ist und ob ein Standard-Block die Anfrage abfängt.
Für HTTPS ist der Test etwas anders, da TLS SNI verwendet, bevor der HTTP-Host-Header verarbeitet wird:
curl --resolve example1.com:443:203.0.113.10 https://example1.com/
Dieser Befehl teilt curl mit, eine Verbindung zu Ihrer Server-IP herzustellen, während für TLS und HTTP weiterhin example1.com verwendet wird. Dies ist eine der schnellsten Möglichkeiten, einen neuen HTTPS-Virtual-Host zu testen, bevor DNS geändert wird.
Ein wartbares Multi-Site-Muster
Für eine Handvoll statischer Seiten reichen die obigen Beispiele aus. Sobald Sie mehrere Anwendungen hosten, wiederholen Sie weniger und zentralisieren Sie nur die Teile, die wirklich gemeinsam genutzt werden. Legen Sie beispielsweise gemeinsame Sicherheitsheader, Komprimierung und SSL-Parameter in Snippets ab, aber behalten Sie root, server_name, Upstream und Logs jeder Seite in ihrer eigenen Datei sichtbar.
Vermeiden Sie es, einen großen Produktionsblock von einer Domain in eine andere zu kopieren, ohne jede Zeile zu lesen. So schleichen sich server_name-Fehler, falsche Zertifikatspfade und gemeinsame Logdateien ein. Eine praktische Überprüfungsliste ist kurz:
- Enthält
server_namejeden Hostnamen, den Benutzer eingeben werden? - Zeigt
rootoderproxy_passauf diese Seite, nicht auf die vorherige? - Sind Zugriffs- und Fehlerlogs ausreichend getrennt, um diese Seite allein debuggen zu können?
- Besteht
nginx -tvor dem Neuladen? - Gibt
curl -H "Host: ..."odercurl --resolvedie erwartete Seite zurück?
Abschließende Bemerkungen
Nginx Virtual Hosts sind zuverlässig, wenn jede Seite einen klaren Server-Block, einen korrekten server_name und einen vorhersehbaren Standard-Fallback hat. Halten Sie die Dateien langweilig. Testen Sie jede Änderung vor dem Neuladen. Verwenden Sie dedizierte Logs, wenn die Seiten wichtig sind. Die meisten Multi-Site-Nginx-Probleme lassen sich leicht lösen, sobald Sie nachweisen können, ob DNS, TLS/SNI oder das Server-Block-Matching der fehlgeschlagene Teil ist.