Nginx für Entwickler: Der Konfigurationsleitfaden, den Sie sich wirklich als Lesezeichen speichern werden
Nginx-Konfigurationen wirken wie Hieroglyphen, bis man das zugrunde liegende Konzept verstanden hat. In diesem Leitfaden wird erklärt, was jede Anweisung tatsächlich bewirkt, und es werden Konfigurationen zum Kopieren und Einfügen für die fünf gängigsten Setups bereitgestellt.
Das mentale Modell: Nginx ist eine Poststelle
Stellen Sie sich Nginx wie eine Poststelle vor. Anfragen gehen an der Rezeption ein (Port 80/443). Die Poststelle überprüft das Adressetikett (server_name), um die Anfrage an die richtige Abteilung weiterzuleiten (Serverblock). Innerhalb der Abteilung wird die Betreffzeile (location) überprüft, um die Anfrage an die richtige Person weiterzuleiten (upstream/file).
Das ist alles. Bei Nginx läuft alles so ab: Eine Anfrage abgleichen → etwas damit tun.
Konfiguration 1: Next.js + Django hinter Nginx (am häufigsten)
# Upstream blocks: define your app servers
upstream frontend {
server frontend_container:3000;
keepalive 16; # reuse connections (huge perf win)
}
upstream backend {
server backend_container:8000;
keepalive 8;
}
server {
listen 443 ssl;
server_name yourapp.com;
# SSL (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/yourapp.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourapp.com/privkey.pem;
# API routes -> Django
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection ""; # required for keepalive
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Admin -> Django
location /admin/ {
proxy_pass http://backend;
proxy_set_header Host $host;
}
# Static files -> Django (with caching)
location /static/ {
proxy_pass http://backend;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Everything else -> Next.js
location / {
proxy_pass http://frontend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_buffering off; # important for streaming SSR
}
}Konfiguration 2: HTTPS-Weiterleitung + www-Canonical
Zwei Dinge, die jede Produktionswebsite benötigt: HTTPS erzwingen und eine kanonische Domain festlegen (mit oder ohne „www“). Ohne diese Maßnahmen betrachtet Google zwei separate Websites, was Ihre SEO-Ergebnisse verwässert.
# Redirect HTTP -> HTTPS
server {
listen 80;
server_name yourapp.com www.yourapp.com;
return 301 https://yourapp.com$request_uri;
}
# Redirect www -> non-www
server {
listen 443 ssl;
server_name www.yourapp.com;
ssl_certificate /etc/letsencrypt/live/yourapp.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourapp.com/privkey.pem;
return 301 https://yourapp.com$request_uri;
}
# Main site (canonical)
server {
listen 443 ssl;
server_name yourapp.com;
# ... your config
}Die 5 Grundsätze, die Sie kennen müssen
| Richtlinie | Funktionsweise | Warum das wichtig ist |
|---|---|---|
| proxy_http_version 1.1 | Verwendet HTTP/1.1 für Upstream-Verbindungen | Erforderlich für die Funktion von Keepalive |
| proxy_set_header Connection "" | Löscht den „Connection“-Header | Ohne diese Angabe ist Keepalive deaktiviert |
| proxy_buffering aus | Die Antwort wird direkt an den Client gesendet | Erforderlich für SSR-Streaming, SSE, Echtzeit |
| client_max_body_size 20 MB | Maximale Upload-Größe | Standardwert ist 1 MB – das Hochladen von Dateien schlägt fehl |
| proxy_set_header X-Forwarded-Proto $scheme | Teilt dem Backend mit, ob die Anfrage über HTTPS erfolgte | Django benötigt dies für CSRF und Weiterleitungen |
Fehlerbehebung: Wenn etwas schiefgeht
502 Bad Gateway: Nginx kann keine Verbindung zu Ihrem Upstream herstellen. Ihr App-Container läuft nicht oder befindet sich in einem anderen Docker-Netzwerk.
504 Gateway-Zeitüberschreitung: Ihre App ist zu langsam. Erhöhen Sie den Wert für „proxy_read_timeout“ oder optimieren Sie Ihre App.
413 Anfrage zu groß: Der Upload überschreitet den Wert für `client_max_body_size`. Erhöhen Sie diesen Wert.
301-Weiterleitungsschleife: Deine App leitet auf HTTPS weiter, aber „X-Forwarded-Proto“ ist nicht gesetzt, sodass sie immer davon ausgeht, dass es sich um HTTP handelt.
# Quick debugging commands
nginx -t # test config syntax
nginx -s reload # reload without downtime
tail -f /var/log/nginx/error.log # watch errors live
curl -I https://yourapp.com # check response headersNginx ist der Türsteher in deinem Club. Es entscheidet, wer reinkommt, wohin die Gäste gehen und wie schnell das geht. Wenn du dir 30 Minuten Zeit nimmst, um es zu verstehen, sparst du dir 30 Stunden Debugging bei Problemen in der Produktion.
— alokknight Engineering
