Einen nginx reverse proxy einzurichten ist der praktischste Weg, ein solides Tor vor deinen Anwendungsserver zu stellen, statt ihn direkt dem Internet auszusetzen. Ob es eine Node.js-API ist, ein PHP-FPM-Prozess, der Laravel bedient, oder eine Game-Panel-Oberfläche, die auf Port 8080 lauscht: Nginx nimmt die eingehenden Anfragen entgegen, beendet TLS, liefert statische Dateien aus und leitet den Rest an die dahinterliegende App weiter. In diesem Artikel bauen wir Schritt für Schritt eine funktionierende Konfiguration von Grund auf, behandeln die typischen Fallstricke und ergänzen die Feinabstimmung, die der Produktivbetrieb braucht.
Was macht ein Reverse Proxy genau?
Ein klassischer Proxy sitzt auf der Client-Seite und verwaltet ausgehenden Verkehr. Ein Reverse Proxy ist das Gegenteil: Er sitzt auf der Server-Seite und verarbeitet den eingehenden Verkehr. Der Client sieht nur Nginx; er weiß nie, auf welchem Port, in welcher Sprache oder in wie vielen Kopien die Backend-App läuft. Diese Abstraktion bringt dir viel:
- TLS-Terminierung: Die Zertifikatsverwaltung wird an einem einzigen Punkt, in Nginx, zentralisiert. Die App spricht einfaches HTTP.
- Ein Port, eine Domain: Du nimmst alles auf 80 und 443 entgegen und leitest verschiedene Pfade (
/api,/admin) an verschiedene Backends weiter. - Sicherheit: Der App-Port bleibt nach außen geschlossen; er ist nur von localhost aus erreichbar.
- Leistung: Statische Dateien, gzip/brotli-Kompression und Caching werden direkt von Nginx verwaltet.
Installation und Grundkonfiguration
Auf Debian/Ubuntu ist die Installation ein Einzeiler:
sudo apt update
sudo apt install nginx
sudo systemctl enable --now nginx
Am saubersten ist es, Konfigurationsdateien unter /etc/nginx/sites-available/ zu halten und sie per Symlink in sites-enabled/ zu aktivieren. Angenommen, deine App läuft auf 127.0.0.1:3000. Der folgende Server-Block leitet alle eingehenden Anfragen an sie weiter:
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
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;
}
}
Aktiviere die Datei, teste die Konfiguration und lade neu:
sudo ln -s /etc/nginx/sites-available/app \
/etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Warum sind die Proxy-Header so wichtig?
Die obigen proxy_set_header-Zeilen sind keine Zierde. In dem Moment, in dem Nginx dazwischentritt, kann die Backend-App den echten Client nicht mehr sehen; ihr gegenüber steht nur 127.0.0.1. Gibst du nicht die richtigen Header weiter, erscheint die IP aller als localhost in deinen Logs, deine App hält HTTPS für HTTP und gerät in eine endlose Weiterleitungsschleife, oder die Sitzungscookies brechen.
X-Forwarded-Forträgt die echte Client-IP.X-Forwarded-Prototeilt der App mit, dass die Anfrage tatsächlich HTTPS war; sichere Cookies und korrekte URL-Erzeugung hängen davon ab.- Das Beibehalten des
Host-Headers lässt die App in Multi-Domain-Setups den richtigen Host sehen.
Vergiss in Frameworks wie Laravel nicht, die trusted proxy-Einstellung zu konfigurieren, damit diese Header berücksichtigt werden; andernfalls werden die X-Forwarded-*-Header ignoriert.
HTTPS und TLS-Terminierung
Die größte Stärke eines Reverse Proxy ist es, das Zertifikat an einem Ort zu zentralisieren. Certbot ist das praktischste Werkzeug, um ein kostenloses Let's-Encrypt-Zertifikat zu erhalten:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d app.example.com
Certbot fügt automatisch den 443-Block, die Zertifikatspfade und die Weiterleitung von 80 auf 443 hinzu. Wenn du es lieber manuell schreibst, sieht das Gerüst so aus:
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_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Da du TLS bei Nginx beendest, kann die Verbindung zum Backend einfaches HTTP sein; über localhost ist das völlig sicher und befreit die App von jeglicher Zertifikatsverwaltung.
WebSocket, Timeouts und Caching
Echtzeit-Apps (Chat, Live-Dashboards, eine Spielkonsole) nutzen WebSocket. Damit Nginx die Verbindung hochstufen kann, sind zwei Header erforderlich:
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_read_timeout 3600s;
}
Bei langlaufenden Anfragen kann dich der voreingestellte proxy_read_timeout von 60 Sekunden täuschen; eine schwere Berichtserstellung wird auf halbem Weg abgeschnitten. Für statische Inhalte beantwortet die Nutzung von Nginx' eigenem Cache oder der expires-Direktive die Anfrage, ohne je das Backend zu erreichen, und entlastet so die App.
Lastverteilung und mehrere Backends
Wenn eine einzelne App-Instanz nicht ausreicht, definierst du mehrere Prozesse als einen Pool mit einem upstream-Block:
upstream app_pool {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
server {
listen 80;
location / {
proxy_pass http://app_pool;
}
}
Standardmäßig verteilt Nginx Anfragen reihum (Round-Robin); mit least_conn wählt es die mit den wenigsten Verbindungen, und mit ip_hash schickt es denselben Client immer an dasselbe Backend. Das ist auch die Grundlage für Bereitstellungen ohne Ausfallzeit (Blau-Grün).
Häufige Fragen
Sind ein Reverse Proxy und ein Load Balancer dasselbe?
Nicht ganz. Jeder Load Balancer verhält sich wie ein Reverse Proxy, aber nicht jeder Reverse Proxy muss Last verteilen. Nginx kann beides: mit einem einzelnen Backend ist es nur ein Proxy, mit mehreren Backends und einem upstream wird es zum Load Balancer.
Wie behebe ich einen 502-Bad-Gateway-Fehler?
Ein 502 bedeutet fast immer, dass das Backend nicht läuft oder die Adresse/der Port in proxy_pass falsch ist. Bestätige mit ss -ltnp, dass die App tatsächlich lauscht, und sieh in /var/log/nginx/error.log nach.
Sollte ich TLS am Backend beenden?
In den meisten Setups nein. TLS bei Nginx zu beenden und über localhost einfaches HTTP zu sprechen ist sowohl einfacher als auch sicher. Nur in strengen Compliance-Szenarien, in denen auch interner Verkehr über das Netz verschlüsselt sein muss, zieht man End-to-End-TLS in Betracht.
Möchtest du deine Infrastruktur hinter Nginx stellen? Wir können gemeinsam ein solides Reverse-Proxy-Setup entwerfen, inklusive TLS, Caching und Bereitstellungen ohne Ausfallzeit. Kontaktiere mich und lass uns über dein Projekt sprechen.