Nginx-Serverblöcke verstehen: Häufige Konfigurationsfragen

Verstehen Sie, wie Nginx-Serverblöcke funktionieren – wie Anfragen der richtigen Domain zugeordnet werden, was innerhalb eines Blocks enthalten ist und wie Sie Multi-Site-Konfigurationen ohne Verwirrung organisieren.

Nginx-Serverblöcke verstehen: Häufige Konfigurationsfragen

Das Verständnis von Nginx-Serverblöcken ist eine der schnellsten Möglichkeiten, Ihre Nginx-Konfiguration weniger mysteriös erscheinen zu lassen. Serverblöcke entscheiden, welche Site eine Anfrage bearbeitet, welche Domainnamen übereinstimmen, welche Dateien ausgeliefert werden und wohin der Proxy-Verkehr geht.

Wenn Sie mehr als eine Domain hosten, HTTP auf HTTPS umleiten oder Apps hinter Nginx betreiben, sind Serverblöcke der Ort, an dem der Großteil dieser Weiterleitung beginnt.

Was ist ein Nginx-Serverblock?

Ein Nginx-Serverblock ist ein Konfigurationsabschnitt, der definiert, wie Nginx für eine bestimmte Kombination aus Adresse, Port und Hostname reagieren soll.

Ein grundlegender Serverblock für eine statische Site sieht so aus:

server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/example.com/public;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Dies weist Nginx an, auf Port 80 zu lauschen, Anfragen für example.com und www.example.com zuzuordnen, Dateien aus dem öffentlichen Verzeichnis auszuliefern und einen 404-Fehler zurückzugeben, wenn eine Datei nicht gefunden wird.

Der Name "Serverblock" ist bei Nginx üblich. Apache-Benutzer kennen ein ähnliches Konzept als virtuellen Host. Der Zweck ist derselbe: Einem Webserver ermöglichen, mehrere Sites oder Apps zu verwalten.

Serverblöcke werden normalerweise in /etc/nginx/sites-available/ gespeichert und auf Debian- und Ubuntu-Systemen mit Symlinks in /etc/nginx/sites-enabled/ aktiviert. Einige Distributionen verwenden stattdessen /etc/nginx/conf.d/. Das genaue Layout ist weniger wichtig als zu wissen, welche Dateien von nginx.conf eingebunden werden.

Wie wählt Nginx den richtigen Serverblock aus?

Die Nginx-Auswahl erfolgt in Stufen. Zuerst werden die IP-Adresse und der Port von der listen-Direktive berücksichtigt. Dann wird der Hostname der Anfrage mit server_name verglichen.

Wenn kein Hostname übereinstimmt, verwendet Nginx den Standard-Server für diese Adresse und diesen Port. Sie können einen explizit markieren:

server {
    listen 80 default_server;
    server_name _;
    return 444;
}

Einige Teams verwenden einen solchen Standardblock, um nicht übereinstimmende Anfragen zu verwerfen. Andere geben einen einfachen 404 zurück. Die beste Wahl hängt von Ihren Logging- und Sicherheitspräferenzen ab.

Wenn Sie noch lernen, kann ein sichtbarer 404-Standard einfacher zu debuggen sein als return 444, da 444 ein Nginx-spezifischer Verbindungsabbruch ist und clientseitig wie ein Netzwerkproblem aussehen kann. In der Produktion bevorzugen einige Teams den stillen Abbruch für zufällige, nicht übereinstimmende Hosts. Beide Optionen sind in Ordnung, wenn das Team sie versteht.

Exakte Namen werden gegenüber Platzhalternamen bevorzugt. Beispielsweise ist api.example.com spezifischer als *.example.com. Regex-Servernamen sind möglich, sollten aber selten sein, da sie schwerer zu lesen und zu beheben sind.

Ein häufiger Fehler ist das Hinzufügen einer neuen Domain zum DNS, aber das Vergessen, sie zu server_name hinzuzufügen. Die Anfrage erreicht den Server, aber Nginx leitet sie an den Standardblock weiter. Aus Benutzersicht erscheint die falsche Site oder die Anfrage schlägt fehl.

Ein weiterer häufiger Fehler ist das Erstellen von zwei Blöcken, die beide dasselbe listen und server_name beanspruchen. Nginx warnt möglicherweise vor widersprüchlichen Servernamen und ignoriert einen davon. Testen Sie die Konfiguration immer nach dem Hinzufügen einer Site.

Verwenden Sie dies, wenn die falsche Site antwortet:

sudo nginx -T | grep -n "server_name"
curl -I -H 'Host: example.com' http://127.0.0.1/

nginx -T gibt die vollständig geladene Konfiguration aus, einschließlich eingebundener Dateien. Das ist oft schneller, als jede Datei unter sites-enabled zu öffnen.

Was gehört in einen Serverblock?

Ein Serverblock enthält normalerweise Direktiven für Domain-Matching, TLS, Dokumentenwurzel, Logging, Weiterleitungen und einen oder mehrere location-Blöcke.

Für einen Reverse-Proxy könnte der Block so aussehen:

server {
    listen 443 ssl;
    server_name app.example.com;

    ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:3000;
    }
}

Hier beendet Nginx HTTPS und leitet den Verkehr an eine lokale Anwendung auf Port 3000 weiter. Dies ist üblich für Node.js-, Python-, Ruby-, Go- und Java-Apps.

Wenn die vorgelagerte App das ursprüngliche Schema oder die Client-IP kennen muss, sind diese proxy_set_header-Zeilen wichtig. Ohne sie könnte die App denken, dass jede Anfrage von 127.0.0.1 über einfaches HTTP kam. Das kann Weiterleitungen, Audit-Logs, Ratenbegrenzungen und generierte Callback-URLs beschädigen.

Verwenden Sie klare Log-Pfade, wenn Sie mehrere Sites hosten:

access_log /var/log/nginx/app.example.com.access.log;
error_log /var/log/nginx/app.example.com.error.log;

Getrennte Logs erleichtern die Fehlerbehebung erheblich. Wenn jede Site in ein gemeinsames Zugriffsprotokoll schreibt, dauert es länger, zu erkennen, welche Domain ausfällt.

Für einen stark frequentierten Host erleichtert dies auch die Aufbewahrung. Möglicherweise möchten Sie detaillierte Logs für eine API während eines Vorfalls und eine leichtere Protokollierung für eine statische Site. Wenn Sie die Dateien getrennt halten, haben Sie diese Option, ohne jeden Serverblock auf einmal ändern zu müssen.

Wie unterscheiden sich Serverblöcke von Location-Blöcken?

Serverblöcke wählen die Site aus. Location-Blöcke wählen aus, was mit Pfaden innerhalb dieser Site geschehen soll.

Zum Beispiel:

server {
    server_name example.com;

    location /assets/ {
        expires 30d;
    }

    location /api/ {
        proxy_pass http://api_backend;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Anfragen für /assets/logo.png erhalten statisches Datei-Caching. Anfragen für /api/users gehen an ein vorgelagertes Backend. Andere Anfragen fallen auf die Frontend-App zurück.

Diese Aufteilung ist wichtig. Wenn die falsche Domain antwortet, überprüfen Sie das Serverblock-Matching. Wenn die richtige Domain antwortet, aber das falsche Pfadverhalten auftritt, überprüfen Sie das Location-Matching.

Diese Unterscheidung spart Zeit. Eine Anfrage für api.example.com/users kann fehlschlagen, weil api.example.com mit dem falschen Serverblock übereinstimmte, oder weil /users mit dem falschen Location innerhalb des richtigen Blocks übereinstimmte. Das sind unterschiedliche Probleme.

Weitere Details zur Pfadweiterleitung finden Sie unter Nginx location blocks explained.

Wie sollte ich mehrere Sites organisieren?

Verwenden Sie nach Möglichkeit eine Datei pro Site oder App. Geben Sie jeder Datei einen Namen, der der Domain oder dem Zweck entspricht:

/etc/nginx/sites-available/example.com
/etc/nginx/sites-available/api.example.com
/etc/nginx/sites-available/admin.example.com

Dies erleichtert Überprüfungen und verringert die Wahrscheinlichkeit, den falschen Dienst zu ändern. Es hilft auch, wenn Sie eine Site schnell deaktivieren müssen.

Halten Sie gemeinsame Snippets klein und offensichtlich. TLS-Einstellungen, Proxy-Header und Sicherheitsheader sind gute Kandidaten für Includes. Vermeiden Sie es, wichtiges Routing-Verhalten in einer generischen Include-Datei zu verstecken, da dies das Debuggen erschwert.

Ein praktisches Setup könnte Folgendes enthalten:

include snippets/proxy-headers.conf;
include snippets/security-headers.conf;

Verwenden Sie Includes, um Wiederholungen zu reduzieren, nicht um jede Site identisch zu verhalten. Ein internes Admin-Panel, eine öffentliche API und eine statische Marketing-Site benötigen oft unterschiedliche Limits und Header.

Bevor Sie eine Serverblock-Datei löschen oder umbenennen, überprüfen Sie, wie sie eingebunden ist. Bei Debian-ähnlichen Layouts bewirkt das Entfernen der Datei aus sites-available nichts, wenn noch eine andere Kopie in conf.d vorhanden ist. Andererseits deaktiviert das Löschen eines Symlinks in sites-enabled die Site, ohne die Quelldatei zu löschen.

ls -l /etc/nginx/sites-enabled/
sudo nginx -T | grep -n "include"

Diese schnelle Überprüfung verhindert den frustrierenden Fall, dass Sie die richtig aussehende Datei bearbeiten und Nginx weiterhin eine andere verwendet.

Wann sollte ich Hilfe bei Serverblock-Problemen suchen?

Bitten Sie einen DevOps-Ingenieur oder Nginx-Spezialisten um Hilfe, wenn Serverblock-Änderungen Produktionsdomains, HTTPS-Zertifikate, kundenorientierte Weiterleitungen oder mehrere Anwendungen auf demselben Host betreffen. Kleine Fehler können Benutzer zur falschen App führen oder die Zertifikatserneuerung unterbrechen.

Sie sollten auch Hilfe suchen, wenn Nginx nach Ihrer Meinung nach korrekter Konfiguration weiterhin die falsche Site ausliefert. Das Problem kann DNS, IPv6, einen Load Balancer, ein CDN oder eine Include-Datei betreffen, die Sie nicht bemerkt haben.

Serverblöcke sind die Karte, die Nginx verwendet, um domainbasierten Verkehr zu leiten. Halten Sie sie spezifisch, testen Sie nach jeder Änderung, verwenden Sie separate Logs und trennen Sie in Ihrem mentalen Modell das Domain-Matching vom Pfad-Routing. Sobald das klickt, werden die meisten Nginx-Konfigurationsfragen viel einfacher zu beantworten sein.