Nginx-Spickzettel: Befehle, Konfigurationsbeispiele und Fehlerbehebung
Kurzreferenz für den täglichen Nginx-Betrieb auf Debian 12 und Ubuntu 24.04. Nach Aufgaben geordnet, damit Sie schnell finden, was Sie brauchen. Eine vollständige Anleitung finden Sie unter Nginx-Administration auf einem VPS.
Wie verwalte ich den Nginx-Dienst?
Verwenden Sie systemctl, um Nginx über systemd zu steuern, oder senden Sie Signale direkt mit nginx -s. Systemctl ist der Standard auf modernen Debian- und Ubuntu-Systemen. Die nativen nginx -s-Befehle kommunizieren direkt mit dem Master-Prozess über seine PID-Datei. Beide funktionieren. Systemctl eignet sich besser für Automatisierung und Boot-Persistenz.
Signal- und Befehlszuordnung
| Aktion | systemctl-Befehl | nginx -s Äquivalent | Unix-Signal | Auswirkung auf Worker |
|---|---|---|---|---|
| Starten | sudo systemctl start nginx |
(nicht anwendbar) | - | Master-Prozess startet, erzeugt Worker |
| Stoppen (graceful) | sudo systemctl stop nginx |
sudo nginx -s quit |
SIGQUIT | Worker beenden laufende Anfragen, dann Beendigung |
| Stoppen (sofort) | sudo systemctl kill nginx |
sudo nginx -s stop |
SIGTERM | Worker trennen Verbindungen und beenden sich |
| Config neu laden | sudo systemctl reload nginx |
sudo nginx -s reload |
SIGHUP | Neue Worker starten mit neuer Config. Alte Worker beenden ihre Anfragen, dann Beendigung. Keine verlorenen Verbindungen. |
| Logs neu öffnen | (nicht integriert) | sudo nginx -s reopen |
SIGUSR1 | Worker öffnen Log-Dateideskriptoren neu. Nach Log-Rotation verwenden. |
| Beim Boot aktivieren + sofort starten | sudo systemctl enable --now nginx |
(nicht anwendbar) | - | Erstellt Symlink für den Boot, startet sofort |
| Deaktivieren + stoppen | sudo systemctl disable --now nginx |
(nicht anwendbar) | - | Entfernt Boot-Symlink, stoppt sofort |
enable --now sorgt dafür, dass Nginx Neustarts überlebt und startet es sofort. Bevorzugen Sie immer diesen Befehl gegenüber einem einfachen start.
Reload vs. Restart
reload sendet SIGHUP. Der Master-Prozess liest die neue Config, erzeugt neue Worker und lässt alte Worker ihre aktiven Verbindungen abarbeiten. Null Ausfallzeit.
restart sendet SIGTERM (Stopp), dann Neustart. Alle aktiven Verbindungen werden getrennt. Verwenden Sie restart nur beim Ändern von Listen-Ports, Laden neuer Module oder Aktualisieren der Nginx-Binary.
Testen Sie immer vor dem Neuladen:
sudo nginx -t && sudo systemctl reload nginx
Wenn nginx -t fehlschlägt, wird das Neuladen nicht ausgeführt. Ihre laufende Config bleibt unangetastet.
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Nach dem Neuladen:
sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-03-20 10:15:32 UTC; 2s ago
Das enabled in der Loaded-Zeile bedeutet, dass Nginx beim Boot startet. Nginx auf Debian 12 und Ubuntu 24.04 aus dem offiziellen Repository installieren
Wie teste und prüfe ich die Nginx-Konfiguration?
Führen Sie nginx -t aus, um die Syntax zu validieren, ohne den laufenden Server zu beeinflussen. nginx -T validiert und gibt die vollständige geparste Config auf stdout aus. nginx -V zeigt Compile-Zeit-Module und Flags.
| Befehl | Zweck |
|---|---|
sudo nginx -t |
Config-Syntax testen, prüfen ob referenzierte Dateien existieren |
sudo nginx -t -q |
Gleicher Test, unterdrückt Nicht-Fehler-Ausgabe (nützlich in Skripten) |
sudo nginx -T |
Test + vollständige geparste Config auf stdout ausgeben |
sudo nginx -V |
Version, Compiler, Configure-Argumente, eingebaute Module anzeigen |
sudo nginx -v |
Nur Versionsnummer anzeigen |
Laufende Config ausgeben und durchsuchen
sudo nginx -T 2>/dev/null | grep -A5 "server_name example.com"
Dieser Befehl gibt die vollständige Config aus (alle eingebundenen Dateien zusammengeführt) und filtert nach einem bestimmten Server-Block. Schneller als das manuelle Öffnen von Dateien, wenn Sie Dutzende Includes haben.
Kompilierte Module prüfen
sudo nginx -V 2>&1 | tr ' ' '\n' | grep module
--with-http_ssl_module
--with-http_v2_module
--with-http_realip_module
--with-http_gzip_static_module
--with-http_stub_status_module
Sie können eine Direktive nicht verwenden, wenn ihr Modul nicht einkompiliert ist. Das ist das Erste, was Sie prüfen sollten, wenn eine Direktive den Fehler „unknown directive" auslöst.
Wo befinden sich die Nginx-Config- und Log-Dateien?
Auf Debian 12 und Ubuntu 24.04 installiert der Paketmanager alles unter /etc/nginx/. Logs werden in /var/log/nginx/ geschrieben. Hier die vollständige Struktur.
| Pfad | Zweck |
|---|---|
/etc/nginx/nginx.conf |
Haupt-Config. Legt Worker-Anzahl, Events, HTTP-Block, Includes fest |
/etc/nginx/sites-available/ |
Server-Block-Dateien (verfügbar, aber nicht unbedingt aktiv) |
/etc/nginx/sites-enabled/ |
Symlinks zu sites-available. Nginx lädt diese. |
/etc/nginx/conf.d/ |
Zusätzliche Config-Fragmente. Werden durch das Standard-include in nginx.conf geladen |
/etc/nginx/snippets/ |
Wiederverwendbare Config-Snippets (SSL-Parameter, Sicherheits-Header) |
/etc/nginx/mime.types |
MIME-Typ-Zuordnungen |
/var/log/nginx/access.log |
Anfragen-Log |
/var/log/nginx/error.log |
Fehler-Log |
/run/nginx.pid |
PID-Datei des Master-Prozesses |
Eine Site aktivieren:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Eine Site deaktivieren:
sudo rm /etc/nginx/sites-enabled/example.com
sudo nginx -t && sudo systemctl reload nginx
Für eine detaillierte Erklärung der Verzeichnisstruktur, siehe Nginx-Konfigurationsdatei: Aufbau und Struktur erklärt.
Was sind die gängigsten Nginx-Config-Snippets?
Jedes Snippet unten ist ein minimales, funktionierendes Beispiel. Kopieren, Werte anpassen, mit nginx -t testen, neu laden. Vollständige Anleitungen zu jedem Thema finden Sie über die internen Links.
Wie richte ich einen einfachen Server-Block ein?
Ein Server-Block (virtueller Host) verbindet eine Domain mit einem Dokumentenstamm. Legen Sie dies in /etc/nginx/sites-available/example.com ab.
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html;
server_tokens off;
location / {
try_files $uri $uri/ =404;
}
}
server_tokens off verbirgt die Nginx-Version in den Antwort-Headern. Versionsoffenlegung hilft Angreifern, bekannte Schwachstellen gezielt auszunutzen.
Erstellen Sie einen Symlink in sites-enabled und laden Sie die Config neu. Nginx Server Blocks: Mehrere Domains auf einem VPS betreiben
Wie leite ich HTTP auf HTTPS um?
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
return 301 ist schneller als rewrite für vollständige URL-Weiterleitungen. Nginx verarbeitet return bevor das Dateisystem berührt wird.
Wie konfiguriere ich Nginx als Reverse Proxy?
Leiten Sie Anfragen an ein Backend auf Port 3000 weiter. Platzieren Sie dies im HTTPS-Server-Block.
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
Der abschließende Schrägstrich ist entscheidend. proxy_pass http://127.0.0.1:3000; (ohne Schrägstrich) leitet die vollständige Original-URI weiter. proxy_pass http://127.0.0.1:3000/; (mit Schrägstrich) entfernt das Location-Präfix. Dies ist die Ursache vieler fehlerhafter Proxy-Konfigurationen.
Nginx als Reverse Proxy konfigurieren
Wie aktiviere ich gzip-Komprimierung?
Fügen Sie dies dem http {}-Block in /etc/nginx/nginx.conf oder einer Snippet-Datei hinzu:
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_min_length 1024;
gzip_comp_level 5;
gzip_types
text/plain
text/css
text/javascript
application/json
application/javascript
application/xml
image/svg+xml;
gzip_min_length 1024 überspringt Dateien unter 1 KB. Das Komprimieren kleiner Dateien verursacht CPU-Overhead ohne nennenswerte Größenreduzierung. gzip_comp_level 5 bietet ein gutes Gleichgewicht zwischen Komprimierungsrate und CPU-Kosten. Über 6 hinaus gibt es abnehmende Erträge.
Nginx Performance-Tuning auf einem VPS
Wie füge ich Rate Limiting hinzu?
Definieren Sie eine Zone im http {}-Block und wenden Sie sie in einem location- oder server-Block an.
# In http {} block
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
# In server or location block
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://127.0.0.1:8080;
}
$binary_remote_addr verwendet 4 Bytes pro IPv4-Adresse. Eine 10-MB-Zone fasst etwa 160.000 Adressen. burst=20 erlaubt kurze Spitzen. nodelay bedient Burst-Anfragen sofort, statt sie in eine Warteschlange zu stellen.
Nginx Rate Limiting und DDoS-Schutz
Wie leite ich WebSocket-Verbindungen weiter?
location /ws/ {
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_read_timeout 86400s;
}
proxy_http_version 1.1 ist erforderlich. HTTP/1.0 unterstützt den Upgrade-Header nicht. proxy_read_timeout 86400s hält inaktive WebSocket-Verbindungen 24 Stunden offen statt der standardmäßigen 60 Sekunden.
Wie richte ich benutzerdefinierte Fehlerseiten ein?
server {
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /404.html {
root /var/www/errors;
internal;
}
location = /50x.html {
root /var/www/errors;
internal;
}
}
Die internal-Direktive verhindert den direkten Zugriff auf die Fehlerseiten-URLs. Ohne sie könnten Benutzer /404.html direkt aufrufen.
Wie füge ich Sicherheits-Header hinzu?
Erstellen Sie /etc/nginx/snippets/security-headers.conf:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Binden Sie es in beliebige Server-Blöcke ein:
include snippets/security-headers.conf;
Der Parameter always fügt Header auch bei Fehlerantworten (4xx, 5xx) hinzu. Ohne ihn setzt Nginx sie nur bei 2xx/3xx. Nginx-Sicherheitshärtung unter Ubuntu und Debian
Minimaler TLS-Server-Block
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
server_tokens off;
# ... location blocks
}
Aktivieren Sie nicht TLSv1 oder TLSv1.1. Beide haben bekannte Schwachstellen und werden von modernen Browsern abgelehnt. Let's Encrypt SSL/TLS für Nginx einrichten auf Debian 12 und Ubuntu 24.04
Wie lese und debugge ich Nginx-Logs?
Nginx schreibt standardmäßig zwei Logs: access.log für jede Anfrage und error.log für Probleme. Beide befinden sich in /var/log/nginx/.
Logs in Echtzeit verfolgen
sudo tail -f /var/log/nginx/error.log
Oder über journald:
journalctl -u nginx -f
Fehler-Log-Schweregrade
Die error_log-Direktive akzeptiert eine Stufe. Von am ausführlichsten bis am wenigsten:
debug > info > notice > warn > error > crit > alert > emerg
Der Standard ist error. Um Debug-Logging temporär zu aktivieren:
error_log /var/log/nginx/error.log debug;
Laden Sie Nginx neu. Debug-Logging ist extrem ausführlich. Deaktivieren Sie es nach der Diagnose, sonst füllt es Ihre Festplatte.
JSON-Format für das Access-Log
Strukturierte Logs lassen sich mit Tools wie jq, Loki oder OpenObserve leichter auswerten.
log_format json_combined escape=json
'{'
'"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"upstream_response_time":"$upstream_response_time",'
'"http_user_agent":"$http_user_agent"'
'}';
access_log /var/log/nginx/access.log json_combined;
Debugging-Werkzeuge
| Befehl | Funktion |
|---|---|
curl -I https://example.com |
Nur Antwort-Header anzeigen. Statuscode, Serverversion, Cache-Header prüfen. |
curl -v https://example.com 2>&1 | head -30 |
Ausführliche Ausgabe: TLS-Handshake, Anfrage-/Antwort-Header. |
sudo nginx -T 2>/dev/null | grep server_name |
Alle konfigurierten Server-Namen über alle Config-Dateien auflisten. |
sudo ss -tlnp | grep nginx |
Zeigt, auf welchen Ports/Adressen Nginx lauscht. |
sudo ls -la /var/log/nginx/ |
Log-Dateigrößen und Berechtigungen prüfen. |
stub_status für Monitoring aktivieren
location /nginx_status {
stub_status;
allow 127.0.0.1;
allow ::1;
deny all;
}
curl http://127.0.0.1/nginx_status
Active connections: 3
server accepts handled requests
1542 1542 4890
Reading: 0 Writing: 1 Waiting: 2
Beschränken Sie stub_status auf localhost oder Ihre Monitoring-IP. Diese Direktive legt Informationen zur Serverlast offen.
Was bedeuten die Nginx-Fehlercodes und wie behebe ich sie?
Wenn Nginx einen HTTP-Fehler zurückgibt, verrät die error.log, was passiert ist. Hier die häufigsten Codes, ihre Bedeutung und die Lösung.
| Code | Name | Typische error.log-Meldung | Häufige Ursache | Lösung |
|---|---|---|---|---|
| 403 | Forbidden | directory index of "/var/www/html/" is forbidden |
Fehlende Index-Datei, falsche Dateiberechtigungen, autoindex off (Standard) |
index.html hinzufügen, Berechtigungen korrigieren (chmod 644 für Dateien, 755 für Verzeichnisse), oder autoindex on aktivieren |
| 404 | Not Found | open() "/var/www/html/page" failed (2: No such file or directory) |
Falscher root-Pfad, falsches try_files, Datei existiert nicht |
root-Direktive prüfen, Dateipfad auf der Festplatte überprüfen |
| 413 | Request Entity Too Large | client intended to send too large body |
Upload überschreitet client_max_body_size (Standard: 1 MB) |
client_max_body_size 50m; im Server- oder Location-Block setzen |
| 502 | Bad Gateway | connect() failed (111: Connection refused) while connecting to upstream |
Backend läuft nicht, falscher Port/Socket in proxy_pass |
Backend starten, Port mit proxy_pass abgleichen |
| 503 | Service Unavailable | no live upstreams while connecting to upstream |
Alle Backends in einem upstream-Block sind down |
Mindestens ein Backend starten, Health-Check-Config prüfen |
| 504 | Gateway Timeout | upstream timed out (110: Connection timed out) while reading response header |
Backend antwortet zu langsam | proxy_read_timeout erhöhen, Backend optimieren, Backend-Logs prüfen |
Einen 502 diagnostizieren
Der 502 ist der häufigste Proxy-Fehler. Gehen Sie schrittweise vor:
# 1. Is the backend running?
sudo ss -tlnp | grep 3000
# 2. Can Nginx reach it?
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:3000/
# 3. What does the error log say?
sudo tail -20 /var/log/nginx/error.log
Wenn ss nichts auf Port 3000 zeigt, ist das Backend down. Wenn curl eine Antwort liefert, Nginx aber 502 zurückgibt, prüfen Sie Socket-Berechtigungen (häufig bei PHP-FPM- oder Gunicorn-Unix-Sockets).
Was sind die häufigsten Nginx-Fehler?
Diese verursachen die meisten Momente von „Ich habe die Config geändert und jetzt ist alles kaputt".
Fehlende Semikola
Jede Direktive muss mit einem Semikolon enden. Nginx gibt einen deutlichen Fehler aus:
nginx: [emerg] unexpected "}" in /etc/nginx/sites-enabled/example.com:12
Der Fehler zeigt auf die Zeile nach dem fehlenden Semikolon, nicht auf die problematische Zeile. Schauen Sie eine Zeile höher.
Verwechslung von root und alias
# root: appends the location to the path
location /images/ {
root /var/www;
# serves /var/www/images/photo.jpg
}
# alias: replaces the location with the path
location /images/ {
alias /var/www/media/;
# serves /var/www/media/photo.jpg
}
Bei alias ist der abschließende Schrägstrich sowohl beim Location als auch beim Alias-Pfad erforderlich. Fehlt er, entstehen 404-Fehler ohne erkennbaren Grund im Error-Log.
Verwirrung bei der Location-Auswertungsreihenfolge
Nginx wertet Locations in dieser Reihenfolge aus, unabhängig von ihrer Position in der Config-Datei:
= /exact- Exakte Übereinstimmung. Wird zuerst geprüft. Bei Treffer sofortiger Stopp.^~ /prefix- Bevorzugtes Präfix. Längste Übereinstimmung gewinnt. Bei Treffer werden alle Regex übersprungen.~ regex- Groß-/Kleinschreibung-sensitiver Regex. Von oben nach unten ausgewertet. Erster Treffer gewinnt.~* regex- Groß-/Kleinschreibung-insensitiver Regex. Gleiche Reihenfolge von oben nach unten./prefix- Standard-Präfix. Längste Übereinstimmung gewinnt. Wird nur verwendet, wenn kein Regex zutraf.
Bei Präfixen zählt die Länge der Übereinstimmung, nicht die Reihenfolge in der Config. Bei Regex zählt die Reihenfolge in der Config, nicht die Länge. Diese zu vermischen, ohne das Prinzip zu verstehen, führt zu unvorhersehbarem Routing.
Abschließender Schrägstrich in proxy_pass
# No trailing slash: passes /app/foo to backend as /app/foo
location /app/ {
proxy_pass http://127.0.0.1:3000;
}
# Trailing slash: strips /app/ and passes /foo to backend
location /app/ {
proxy_pass http://127.0.0.1:3000/;
}
Entscheiden Sie sich für eine Variante und bleiben Sie konsistent. Die meisten Backends erwarten den vollständigen Pfad (kein abschließender Schrägstrich bei proxy_pass).
nginx -t vor dem Neuladen vergessen
Wenn Sie mit einer fehlerhaften Config neu laden, läuft Nginx weiter mit der alten Config und protokolliert einen Fehler. Es stürzt nicht ab. Aber Sie haben jetzt eine Config auf der Festplatte, die nicht der laufenden Config entspricht. Das sorgt später für Verwirrung.
Machen Sie es zur Gewohnheit: sudo nginx -t && sudo systemctl reload nginx. Das && stellt sicher, dass das Neuladen nur ausgeführt wird, wenn der Test erfolgreich ist.
sites-available bearbeiten ohne Symlink
Dateien in /etc/nginx/sites-available/ werden nicht automatisch geladen. Sie müssen einen Symlink nach /etc/nginx/sites-enabled/ erstellen. Eine direkte Kopie funktioniert auch, aber Symlinks bewahren eine einzige Quelle der Wahrheit.
Etwas funktioniert nicht?
Schnelle Diagnosesequenz, wenn Nginx sich merkwürdig verhält:
# Check if Nginx is running
sudo systemctl status nginx
# Test the config
sudo nginx -t
# Check which config is actually loaded
sudo nginx -T 2>/dev/null | head -50
# Check the last 30 error log entries
sudo tail -30 /var/log/nginx/error.log
# Check what ports Nginx is listening on
sudo ss -tlnp | grep nginx
# Check file permissions on the web root
sudo ls -la /var/www/example.com/html/
Wenn der Dienst fehlgeschlagen ist, liefert journalctl -u nginx --no-pager -n 50 die vollständige Geschichte. Suchen Sie nach [emerg]-Einträgen.
Bereit, es selbst auszuprobieren?
Stellen Sie Ihren eigenen Server in Sekunden bereit. Linux, Windows oder FreeBSD. →