Nginx-Konfigurationsdatei: Aufbau und Struktur erklaert
Eine vollstaendige Anleitung zum Aufbau der Nginx-Konfigurationsdateien: Verzeichnisstruktur, verschachtelte Kontexte, Include-Direktiven und die Vererbungsregeln, die in der Praxis oft zu Fehlern fuehren.
Nginx-Konfigurationsdatei: Aufbau und Struktur erklaert
Sie haben Nginx installiert. Sie haben /etc/nginx/nginx.conf geoeffnet und eine Datei vorgefunden, die andere Dateien einbindet, die wiederum weitere Dateien einbinden. Manche Direktiven stehen in geschweiften Klammern, andere stehen ganz oben. Bevor Sie mit Server-Bloecken, SSL oder Reverse Proxies anfangen, brauchen Sie die Uebersichtskarte.
Dieser Artikel liefert genau das. Keine Rezepte. Nur das mentale Modell, wie die Nginx-Konfiguration funktioniert, damit Sie jede Konfiguration lesen und anpassen koennen.
Wo liegen die Nginx-Konfigurationsdateien?
Unter Debian 12 und Ubuntu 24.04 installiert das apt-Paket alles unter /etc/nginx/. So sieht das Verzeichnis nach einer frischen Installation aus:
/etc/nginx/
├── nginx.conf # Main config entry point
├── mime.types # Maps file extensions to MIME types
├── conf.d/ # Drop-in config files (*.conf auto-included)
├── sites-available/ # All virtual host config files
│ └── default # Default server block
├── sites-enabled/ # Symlinks to active virtual hosts
│ └── default -> ../sites-available/default
├── snippets/ # Reusable config fragments
│ └── fastcgi-php.conf
├── modules-available/ # Available dynamic module configs
├── modules-enabled/ # Symlinks to loaded modules
├── fastcgi.conf # FastCGI directive defaults
├── fastcgi_params # FastCGI parameter mappings
├── proxy_params # Proxy header defaults
├── scgi_params # SCGI parameter mappings
├── uwsgi_params # uWSGI parameter mappings
├── koi-utf # Character set mapping files
├── koi-win
└── win-utf
Sie koennen das auf Ihrem eigenen Server pruefen:
ls -la /etc/nginx/
Die Datei, die Sie am haeufigsten bearbeiten, ist nicht nginx.conf selbst. Ueblicherweise ist es eine Datei in sites-available/ oder conf.d/. Die Hauptdatei nginx.conf setzt globale Standardwerte und bindet diese Dateien ueber include-Direktiven ein.
Wie sind die Nginx-Konfigurationsdateien aufgebaut?
Die Nginx-Konfiguration verwendet einen Baum aus verschachtelten Kontexten (Contexts). Jeder Kontext ist eine Blockdirektive in geschweiften Klammern. Direktiven innerhalb eines Kontexts gelten nur in diesem Gueltigkeitsbereich.
Die Hierarchie sieht so aus:
main (top level, outside any braces)
├── events { }
└── http { }
└── server { }
└── location { }
Jede Direktive in der Konfiguration lebt auf einer dieser Ebenen. Der Main-Kontext ist die Datei selbst. Alles andere ist darin verschachtelt.
Was steuert der Main-Kontext?
Der Main-Kontext umfasst alles ausserhalb von Blockdirektiven in nginx.conf. Er steuert prozessweite Einstellungen, die die gesamte Nginx-Instanz betreffen.
Wichtige Direktiven auf dieser Ebene:
| Direktive | Zweck | Typischer Wert |
|---|---|---|
user |
Betriebssystem-Benutzer fuer die Worker-Prozesse | www-data |
worker_processes |
Anzahl der Worker-Prozesse | auto (entspricht der Anzahl CPU-Kerne) |
pid |
Pfad zur PID-Datei | /run/nginx.pid |
error_log |
Globaler Fehlerlog-Pfad und -Level | /var/log/nginx/error.log |
include |
Modulkonfigurationen laden | /etc/nginx/modules-enabled/*.conf |
Hier ist der Main-Kontext aus der Standard-nginx.conf von Debian 12:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
Diese fuenf Zeilen werden vor allem anderen ausgefuehrt. Sie legen fest, unter welchem Benutzer Nginx laeuft, wie viele Worker gestartet werden und wohin Fehler geschrieben werden.
Was gehoert in den Events-Block?
Der events-Block konfiguriert, wie Nginx Verbindungen auf Betriebssystemebene verwaltet. Er befindet sich im Main-Kontext.
events {
worker_connections 768;
# multi_accept on;
}
worker_connections legt die maximale Anzahl gleichzeitiger Verbindungen pro Worker-Prozess fest. Mit worker_processes auto auf einem 4-Kern-Rechner erhalten Sie 4 x 768 = 3.072 gleichzeitige Verbindungen. Der Standardwert im Nginx-Quellcode ist 512, Debian setzt ihn auf 768.
Wofuer ist der HTTP-Kontext?
Der http-Block enthaelt die gesamte Konfiguration fuer die HTTP-Verarbeitung. Jeder server-Block lebt darin. Direktiven, die Sie hier platzieren, gelten fuer alle virtuellen Hosts, sofern kein server- oder location-Block sie ueberschreibt.
http {
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Beachten Sie server_tokens off; am Anfang. Diese Direktive verbirgt die Nginx-Versionsnummer in den Response-Headern. Die Offenlegung der Version hilft Angreifern, bekannte Schwachstellen gezielt auszunutzen. Die Debian-Standardkonfiguration enthaelt diese Zeile nicht. Fuegen Sie sie hinzu.
Die beiden include-Zeilen am Ende binden Ihre eigentlichen Website-Konfigurationen ein. Im folgenden Abschnitt behandeln wir include im Detail.
Wie funktionieren Server-Bloecke?
Ein server-Block definiert einen virtuellen Host (Virtual Host). Er lebt innerhalb des http-Kontexts. Jeder server-Block lauscht auf einer Adress-/Port-Kombination und ordnet Anfragen anhand des Host-Headers zu.
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Wenn eine Anfrage eintrifft, waehlt Nginx den server-Block, indem es server_name mit dem Host-Header abgleicht. Wenn kein Block passt, verwendet Nginx den default_server:
listen 80 default_server;
Ueblicherweise erstellen Sie pro Domain eine Datei in sites-available/, die jeweils einen server-Block enthaelt (oder zwei, wenn Sie sowohl HTTP als auch HTTPS verwenden).
Wie gleicht Nginx Location-Bloecke ab?
Ein location-Block legt fest, wie Nginx Anfragen fuer bestimmte URI-Muster verarbeitet. Er befindet sich innerhalb eines server-Blocks (oder innerhalb eines anderen location-Blocks).
Nginx wertet Location-Bloecke in einer bestimmten Reihenfolge aus:
| Modifier | Typ | Beispiel | Verhalten |
|---|---|---|---|
= |
Exakter Treffer | location = / |
Passt nur auf /. Suche wird sofort beendet. |
^~ |
Priorisierter Prefix | location ^~ /images/ |
Passt auf den Prefix. Ueberspringt Regex-Pruefungen. |
~ |
Regex (Gross-/Kleinschreibung beachten) | location ~ \.php$ |
Erster Regex-Treffer gewinnt. |
~* |
Regex (Gross-/Kleinschreibung ignorieren) | location ~* \.(jpg|png)$ |
Erster Regex-Treffer gewinnt. |
| (keiner) | Prefix | location /api/ |
Laengster Prefix gewinnt, aber Regex kann ueberschreiben. |
Der Matching-Algorithmus:
- Nginx prueft alle Prefix-Locations und merkt sich den laengsten Treffer.
- Wenn dieser Treffer
=oder^~verwendet, wird gestoppt und dieser verwendet. - Andernfalls werden Regex-Locations in der Reihenfolge ihres Auftretens in der Konfigurationsdatei geprueft.
- Der erste Regex-Treffer gewinnt. Wenn kein Regex passt, wird der laengste Prefix aus Schritt 1 verwendet.
Das bedeutet: Die Reihenfolge der Prefix-Locations in der Konfigurationsdatei spielt keine Rolle. Aber die Reihenfolge der Regex-Locations ist entscheidend.
Wie funktioniert die Include-Direktive?
Die include-Direktive fuegt den Inhalt einer anderen Datei (oder aller Dateien, die einem Glob-Muster entsprechen) an der aktuellen Position in die Konfiguration ein. Nginx loest sie beim Laden der Konfiguration auf, bevor die Konfiguration als Ganzes geparst wird.
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
Der Glob *.conf passt auf alle Dateien mit der Endung .conf in diesem Verzeichnis. Der Glob * passt auf alles. Beide Muster sind gaengig.
Die include-Direktive funktioniert in jedem Kontext. Sie koennen sie innerhalb von http-, server- oder location-Bloecken verwenden:
server {
listen 443 ssl;
include snippets/ssl-params.conf;
}
So funktioniert das snippets/-Verzeichnis. Sie schreiben ein wiederverwendbares Fragment einmal und binden es ueberall dort ein, wo Sie es benoetigen.
Ein Punkt, auf den Sie achten sollten: Nginx startet nicht, wenn ein include-Pfad ohne Glob auf eine nicht vorhandene Datei verweist. Wenn Sie include /etc/nginx/conf.d/*.conf; schreiben und das Verzeichnis leer ist, startet Nginx problemlos (Globs duerfen auf nichts passen). Aber include /etc/nginx/ssl.conf; schlaegt fehl, wenn diese Datei nicht existiert.
Was ist der Unterschied zwischen sites-available, sites-enabled und conf.d?
Diese drei Verzeichnisse dienen unterschiedlichen Zwecken. Debian und Ubuntu verwenden alle drei.
| Verzeichnis | Zweck | Wie Nginx es liest | Wann verwenden |
|---|---|---|---|
sites-available/ |
Speichert alle Virtual-Host-Konfigurationen | Wird nicht direkt gelesen | Immer. Eine Datei pro Domain. |
sites-enabled/ |
Enthaelt Symlinks zu aktiven Konfigurationen | Eingebunden ueber include /etc/nginx/sites-enabled/*; |
Symlink erstellen, um eine Website zu aktivieren. |
conf.d/ |
Ergaenzende Konfigurationsfragmente | Eingebunden ueber include /etc/nginx/conf.d/*.conf; |
Globale HTTP-Einstellungen, Upstream-Bloecke, Maps. |
Das Muster sites-available / sites-enabled ermoeglicht es, eine Website zu deaktivieren, ohne ihre Konfiguration zu loeschen. Um eine Website zu aktivieren:
ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Um sie zu deaktivieren:
rm /etc/nginx/sites-enabled/example.com
Dann neu laden:
sudo nginx -t && sudo systemctl reload nginx
Fuehren Sie immer nginx -t vor dem Neuladen aus. Das validiert die Konfiguration, ohne den laufenden Datenverkehr zu beeintraechtigen.
Das Verzeichnis conf.d/ ist einfacher. Jede .conf-Datei darin wird automatisch geladen. Keine Symlinks noetig. Manche Administratoren bevorzugen conf.d/ wegen der Einfachheit und verzichten komplett auf sites-available/sites-enabled. Beide Ansaetze funktionieren. Waehlen Sie einen und bleiben Sie konsistent.
Ein Fallstrick: Wenn Sie sowohl conf.d/ als auch sites-enabled/ verwenden, stellen Sie sicher, dass Sie keine widerspruechlichen server-Bloecke an beiden Stellen definieren. Nginx laedt beide, und das Ergebnis haengt von den Regeln zur Direktiven-Zusammenfuehrung und dem server_name-Matching ab.
Wie funktioniert die Direktiven-Vererbung in Nginx?
Nginx reicht Direktiven von uebergeordneten Kontexten an untergeordnete Kontexte weiter. Das ist der Teil, den die meisten Leute falsch verstehen, und die Ursache subtiler Produktionsfehler.
Es gibt drei Typen von Direktiven, und jeder vererbt anders.
Normale Direktiven
Normale Direktiven halten einen einzelnen Wert. Wenn ein untergeordneter Kontext dieselbe Direktive definiert, ersetzt er den Wert des uebergeordneten Kontexts vollstaendig. Wenn der untergeordnete Kontext sie nicht definiert, wird der Wert des uebergeordneten Kontexts vererbt.
Beispiel: root ist eine normale Direktive.
http {
root /var/www/default;
server {
server_name example.com;
# root is inherited: /var/www/default
location /app {
root /var/www/app;
# root is overridden: /var/www/app
}
location /blog {
# root is inherited: /var/www/default
}
}
}
Weitere normale Direktiven: index, access_log (bei einmaliger Verwendung), error_log, client_max_body_size.
Array-Direktiven
Array-Direktiven koennen mehrfach im selben Kontext erscheinen, um Werte zu akkumulieren. Aber sobald ein untergeordneter Kontext auch nur eine Instanz definiert, werden alle Werte des uebergeordneten Kontexts ersetzt. Nicht zusammengefuehrt. Ersetzt.
add_header ist die bekannteste Array-Direktive. Dieses Verhalten verursacht einen weitverbreiteten Produktionsfehler.
Was passiert, wenn Sie Header sowohl im HTTP- als auch im Location-Block setzen?
Wenn Sie add_header im http-Kontext definieren und dann ein anderes add_header in einem location-Block setzen, loescht der Location-Block alle Header aus dem HTTP-Kontext. Nicht nur den einen, den Sie ueberschreiben. Alle.
http {
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
server {
server_name example.com;
location /api/ {
add_header X-Custom "api-response";
# X-Frame-Options is GONE
# X-Content-Type-Options is GONE
# Only X-Custom is sent
}
}
}
Um das auf Ihrem Server zu pruefen:
curl -I https://example.com/api/
Pruefen Sie die Response-Header. Wenn Ihre Sicherheitsheader bei /api/-Antworten fehlen, aber auf anderen Pfaden vorhanden sind, ist das die Ursache.
Die Loesung: Alle Header im untergeordneten Kontext wiederholen.
location /api/ {
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-Custom "api-response";
}
Oder ein Snippet verwenden:
# /etc/nginx/snippets/security-headers.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=63072000" always;
location /api/ {
include snippets/security-headers.conf;
add_header X-Custom "api-response";
}
Hinweis: Ab Nginx 1.29.3 gibt es add_header_inherit merge;, das dieses Verhalten aendert. Mit merge fuegen untergeordnete Kontexte ihre Header an die des uebergeordneten Kontexts an, anstatt sie zu ersetzen. Wenn Sie Nginx 1.28.x verwenden (die aktuelle Stable-Version, Stand Maerz 2026), steht Ihnen das noch nicht zur Verfuegung.
Dasselbe Loeschverhalten gilt fuer proxy_set_header. Wenn Sie ein beliebiges proxy_set_header in einem location-Block definieren, gehen alle proxy_set_header-Direktiven aus dem server- oder http-Kontext verloren. Die offizielle Dokumentation formuliert es eindeutig: "These directives are inherited from the previous configuration level if and only if there are no proxy_set_header directives defined on the current level."
server {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location /api/ {
proxy_set_header X-Request-ID $request_id;
# Host, X-Real-IP, X-Forwarded-For are all GONE
proxy_pass http://backend;
}
}
Die Loesung ist dieselbe: Alle Header im Location-Block wiederholen oder ein Include-Snippet verwenden.
Action-Direktiven
Action-Direktiven wie rewrite und return werden nicht in verschachtelte Kontexte vererbt. Sie werden nur in dem Kontext ausgefuehrt, in dem sie definiert sind.
server {
rewrite ^/old/(.*)$ /new/$1 permanent;
location /app {
# The rewrite above does NOT apply here
# Requests matching /app are handled by this location
}
}
Die Direktive try_files hat einen verwandten Fallstrick. Wenn sie im server-Kontext platziert wird, erstellt Nginx eine implizite Pseudo-Location mit der niedrigstmoeglichen Prioritaet. Wenn ein regulaerer location-Block die Anfrage trifft, wird try_files auf Server-Ebene nie ausgefuehrt:
server {
try_files $uri /index.php; # Never runs for /app/* requests
location /app { } # This catches them first
}
Platzieren Sie try_files immer innerhalb eines spezifischen location-Blocks.
Wie pruefen Sie die effektive Nginx-Konfiguration?
Zwei Befehle helfen Ihnen zu verstehen, was Nginx nach dem Aufloesen aller include-Direktiven tatsaechlich sieht.
Konfiguration auf Syntaxfehler pruefen:
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Fuehren Sie das immer vor dem Neuladen aus. Bei einem Fehler nennt Nginx die Datei und Zeilennummer.
Gesamte zusammengefuehrte Konfiguration ausgeben:
sudo nginx -T
Dieser Befehl gibt die gesamte effektive Konfiguration aus, mit allen aufgeloesten und inline expandierten Includes. Leiten Sie die Ausgabe an less weiter:
sudo nginx -T | less
Oder suchen Sie nach einer bestimmten Direktive:
sudo nginx -T | grep -n "add_header"
Das zeigt jede add_header-Direktive ueber alle eingebundenen Dateien hinweg, mit Zeilennummern in der zusammengefuehrten Ausgabe. Verwenden Sie das beim Debugging von Vererbungsproblemen. Wenn ein Header im HTTP-Block erscheint, aber nicht in einem Location-Block, und Sie kein add_header in diesem Location-Block sehen, wird der Header vererbt. Wenn Sie ein anderes add_header im Location-Block sehen, werden alle uebergeordneten Header geloescht.
Verwenden Sie nginx -T, wann immer Konfigurationsaenderungen sich nicht wie erwartet verhalten.
Kurzreferenz: das Gesamtbild
/etc/nginx/nginx.conf
│
├─ main context (process-level: user, worker_processes, pid)
│
├─ events { } (connection handling: worker_connections)
│
└─ http { } (all HTTP config)
│
├─ include conf.d/*.conf (global HTTP settings, upstreams, maps)
├─ include sites-enabled/* (virtual host configs)
│
└─ server { } (one per domain/port)
│
├─ listen, server_name (routing)
├─ root, index (defaults for this host)
│
└─ location { } (URI pattern matching)
├─ try_files, root (per-path behavior)
└─ proxy_pass (reverse proxy target)
Inheritance: parent -> child (down only)
Normal directives: child overrides parent
Array directives: child REPLACES ALL parent values
Action directives: no inheritance
Copyright 2026 Virtua.Cloud. Alle Rechte vorbehalten. Dieser Inhalt ist ein Originalwerk des Virtua.Cloud-Teams. Vervielfaeltigung, Wiederveroeffentlichung oder Weiterverbreitung ohne schriftliche Genehmigung ist untersagt.
Bereit, es selbst auszuprobieren?
Stellen Sie Ihren eigenen Server in Sekunden bereit. Linux, Windows oder FreeBSD.
VPS-Angebote ansehen