Hinter den meisten modernen Webseiten und APIs steht ein Stück Software, das kaum jemand direkt sieht, aber alles zusammenhält: der Webserver. Nginx (ausgesprochen „Engine X") hat sich seit seiner Veröffentlichung 2004 zur dominanten Kraft entwickelt – es bedient laut Netcraft über 30 Prozent aller aktiven Webseiten weltweit. Der Grund liegt in seiner Event-getriebenen Architektur: Nginx kann Zehntausende gleichzeitige Verbindungen mit minimalem Speicherverbrauch verwalten, weil es Anfragen nicht wie Apache in separaten Threads, sondern asynchron in einem einzigen Prozess abarbeitet.
Was Nginx kann – und was es ist
Nginx übernimmt in modernen Infrastrukturen mehrere Rollen gleichzeitig: Als Webserver liefert es statische Dateien (HTML, CSS, Bilder) extrem schnell aus. Als Reverse-Proxy leitet es Anfragen an Anwendungsserver wie Node.js, Python oder PHP-FPM weiter und schirmt diese vom direkten Internet ab. Als Load Balancer verteilt es Last auf mehrere Backend-Instanzen. Als TLS-Terminator handhabt es HTTPS, damit Backends sich nicht um SSL kümmern müssen.
Statische Dateien ausliefern
Die grundlegendste Konfiguration serviert statische Dateien aus einem Verzeichnis. Konfigurationsdateien für Webseiten liegen unter /etc/nginx/sites-available/ und werden per Symlink nach /etc/nginx/sites-enabled/ aktiviert:
server {
listen 80;
server_name beispiel.de www.beispiel.de;
root /var/www/beispiel.de/public;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# Caching-Header für statische Assets
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Der server_name-Block definiert, für welche Domains diese Konfiguration gilt. location-Blöcke erlauben es, unterschiedliche Verarbeitungsregeln für verschiedene URL-Pfade festzulegen – eine der mächtigsten Funktionen in Nginx.
Reverse-Proxy für Node.js und PHP
Das häufigste Einsatzszenario: Nginx nimmt externe Anfragen entgegen und leitet sie an eine lokal laufende Anwendung weiter:
# Reverse Proxy für Node.js (läuft auf Port 3000)
server {
listen 80;
server_name api.beispiel.de;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_cache_bypass $http_upgrade;
}
}
# PHP-FPM für WordPress/Laravel
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Die Header X-Real-IP und X-Forwarded-For sind wichtig, damit die Anwendung die echte Client-IP-Adresse sieht – nicht die Loopback-Adresse des Proxys.
nginx -t && systemctl reload nginx. Der Reload-Befehl startet Nginx nicht neu – bestehende Verbindungen bleiben aktiv, nur neue Anfragen nutzen die aktualisierte Konfiguration.
SSL mit Let's Encrypt und Certbot
HTTPS ist heute Pflicht. Let's Encrypt bietet kostenlose, automatisch verlängerbare TLS-Zertifikate. Mit Certbot ist die Einrichtung auf Ubuntu/Debian ein Zweizeiler:
apt install certbot python3-certbot-nginx
certbot --nginx -d beispiel.de -d www.beispiel.de
Certbot erkennt die Nginx-Konfiguration automatisch, beantragt das Zertifikat und ergänzt die HTTPS-Server-Blöcke. Die automatische Verlängerung übernimmt ein Systemd-Timer. Das Ergebnis sieht dann ungefähr so aus:
server {
listen 443 ssl;
server_name beispiel.de;
ssl_certificate /etc/letsencrypt/live/beispiel.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/beispiel.de/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# ... rest der Konfiguration
}
Gzip-Komprimierung und Rate Limiting
Zwei Optimierungen, die mit wenigen Zeilen großen Effekt haben:
# Gzip in nginx.conf (http-Block)
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript
text/xml application/xml image/svg+xml;
# Rate Limiting (server- oder location-Block)
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://127.0.0.1:3000;
}
Gzip reduziert die Übertragungsgröße typischer HTML/JSON-Antworten um 60–80 Prozent. Das Rate Limiting erlaubt 10 Anfragen pro Sekunde pro IP, mit einem Burst von 20 Anfragen – danach antwortet Nginx mit HTTP 429, bevor der Backend-Server überhaupt belastet wird.
gzip_types-Liste enthält bewusst keine Binärformate.
Nginx vs. Apache vs. Caddy vs. Traefik
| Merkmal | Nginx | Apache | Caddy | Traefik |
|---|---|---|---|---|
| Architektur | Event-driven, async | Threaded / Event MPM | Event-driven, async | Event-driven, async |
| Konfigurationsstil | Eigene Syntax (Blöcke) | .htaccess / Apache-Syntax | Caddyfile (minimalistisch) | YAML / Docker Labels |
| Automatisches SSL | Nein (Certbot nötig) | Nein (Certbot nötig) | Ja (eingebaut) | Ja (eingebaut) |
| Performance (statisch) | Sehr hoch | Mittel | Hoch | Hoch |
| Typischer Einsatz | Web, API, LB | PHP, .htaccess-Applikationen | Einfacher HTTPS-Server | Container-Umgebungen |
| Lernkurve | Mittel | Mittel | Gering | Mittel (mit Docker vertraut sein) |
Weiterführende Ressourcen
Die offizielle Nginx-Dokumentation ist umfassend und enthält vollständige Referenzen aller Direktiven. Für optimale Sicherheitseinstellungen empfiehlt sich der Mozilla SSL Configuration Generator, der aktuelle, gehärtete SSL-Konfigurationen für Nginx und andere Server generiert. Wer Nginx in Container-Umgebungen einsetzen möchte, findet mit Traefik eine ausgezeichnete Alternative mit automatischer Service Discovery.
Häufige Fragen zu Nginx
- Was ist der Unterschied zwischen location = /pfad, location /pfad und location ~ /regex?
- Nginx wertet Location-Blöcke in einer definierten Reihenfolge aus.
location = /pfadist eine exakte Übereinstimmung mit höchster Priorität.location /pfadist eine Präfix-Übereinstimmung.location ~ist ein regulärer Ausdruck (case-sensitive),location ~*case-insensitiv. Der genaueste Match gewinnt, wobei exakte Übereinstimmungen immer Vorrang haben. - Wie konfiguriere ich Nginx als Load Balancer für mehrere Backend-Server?
- Mit dem
upstream-Block:upstream backend { server 10.0.0.1:3000; server 10.0.0.2:3000; }. Dann in der Location:proxy_pass http://backend;. Standard ist Round-Robin. Alternativ sindleast_conn(wenigste aktive Verbindungen) oderip_hash(Sticky Sessions) konfigurierbar. - Nginx startet nicht – wie debugge ich Konfigurationsfehler?
nginx -tprüft die Konfiguration und gibt die genaue Fehlerstelle aus. Detailliertere Logs finden sich in/var/log/nginx/error.log. Häufige Fehler sind fehlende Semikolons, nicht übereinstimmende geschweifte Klammern oder Pfade zu nicht existierenden Zertifikatsdateien.- Kann Nginx HTTP/3 und QUIC unterstützen?
- Ja, ab Nginx 1.25 ist experimentelle HTTP/3-Unterstützung (QUIC) eingebaut. Sie muss beim Kompilieren aktiviert oder über offizielle Pakete von nginx.org bezogen werden. Die Konfiguration erfordert
listen 443 quic reuseport;neben dem normalen HTTPS-Listener und einen entsprechendenadd_header Alt-Svc-Header.