Zum Inhalt springen
Planen wir gemeinsam die passende Software für Ihre Prozesse. Demo oder Angebot: +90 546 737 48 29

TR EN DE

Nginx als Reverse Proxy einrichten

Ein Reverse Proxy ist ein Server, der zwischen den Besuchern und Ihrer Anwendung steht: Er nimmt die Anfrage aus dem Internet entgegen, leitet sie an die Anwendung dahinter weiter und schickt deren Antwort an den Besucher zurück. Der Besucher sieht nur den Reverse Proxy und weiß nicht, auf welchem Port oder in welcher Sprache die Anwendung läuft.

Anwendungen in Node.js, Python, Java, .NET oder Go laufen meist mit einem eigenen kleinen Webserver auf einem Port wie 3000 oder 8080. Statt eine solche Anwendung direkt ins Internet zu stellen, setzt man Nginx davor: So lassen sich mehrere Anwendungen unter einer Adresse anbieten, HTTPS an einer Stelle verwalten, statische Dateien schnell ausliefern und Grenzen wie Anfragegröße und Zeitüberschreitung (Timeout) zentral festlegen. Das Konzept selbst erklärt die Anleitung Was ist ein Reverse Proxy?.

Diese Anleitung baut Schritt für Schritt eine funktionierende Konfiguration für einen einzelnen Backend-Server auf. In den Beispielen lautet die Domain beispiel.de und die Adresse der Anwendung 127.0.0.1:3000.

Kurz gefasst

  • Nginx nimmt die Anfrage entgegen und leitet sie mit proxy_pass an die Anwendung dahinter weiter.
  • Ein Schrägstrich am Ende von proxy_pass verändert den Pfad, der an das Backend geht.
  • Ohne Host- und X-Forwarded-*-Header sieht die Anwendung weder die echte IP noch https.
  • Nach jeder Änderung mit nginx -t testen, dann neu laden.

Das brauchen Sie

  • Ein Server mit installiertem Nginx und Administratorrechte (sudo)
  • Eine auf dem Server laufende Anwendung und der Port, auf dem sie lauscht (im Beispiel 127.0.0.1:3000)
  • Eine Domain, die auf die IP-Adresse des Servers zeigt
  • Eine SSH-Sitzung, in der Sie die Konfigurationsdateien bearbeiten können

Hinweis

Die Beispiele zeigen nur Port 80 (HTTP). Eine produktive Website braucht zusätzlich HTTPS; Zertifikat und die Einstellungen für Port 443 behandelt eine eigene Anleitung.

Auf dieser Seite

Einrichtung Schritt für Schritt

  1. Die Anwendung nur auf der lokalen Adresse lauschen lassen

    Laufen Nginx und die Anwendung auf demselben Server, sollte die Anwendung auf 127.0.0.1 statt auf 0.0.0.0 (alle Netzwerkschnittstellen) lauschen. Dann erreicht sie nur der Nginx auf demselben Server; niemand kann Nginx umgehen und sich direkt mit http://server-ip:3000 verbinden.

    Läuft die Anwendung auf einem anderen Server, binden Sie sie an die interne Netzwerkadresse (z. B. 10.0.0.5) und erlauben Sie in der Firewall nur dem Nginx-Server den Zugriff auf diesen Port. Dieser Schritt ist auch die Voraussetzung dafür, dass die später beschriebene Einstellung zur „echten IP“ sicher ist.

    Schema: Die Anfrage des Clients erreicht den Nginx-Reverse-Proxy; Nginx leitet sie mit proxy_pass an die nur lokal lauschende Anwendung weiter und ergänzt Header : Vergrößern
  2. Den server-Block anlegen

    In Nginx wird jede Website durch einen server-Block definiert. Legen Sie eine neue Konfigurationsdatei an. Der Ort hängt von der Distribution ab: .conf-Dateien unter /etc/nginx/conf.d/ sind eine verbreitete Struktur; Debian und Ubuntu verwenden /etc/nginx/sites-available/ zusammen mit sites-enabled/.

    Nginx
    # Beispieldatei: /etc/nginx/conf.d/beispiel.de.conf (Pfad je nach Distribution)
    server {
        listen 80;
        server_name beispiel.de www.beispiel.de;
    
        location / {
            # Alle Anfragen an die Anwendung hinter Nginx weiterleiten
            proxy_pass http://127.0.0.1:3000;
        }
    }

    listen legt den Port fest, auf dem gelauscht wird, server_name die Domainnamen, für die dieser Block antwortet. Der Block location / umfasst alle Adressen; die Direktive proxy_pass darin gibt an, wohin die Anfrage weitergeleitet wird.

  3. proxy_pass und den abschließenden Schrägstrich richtig verwenden

    Hier passiert der häufigste Fehler. Steht in der proxy_pass-Adresse nach dem Servernamen ein Pfad (auch nur ein einzelnes /), ersetzt Nginx den Teil der Anfrage, der auf die location gepasst hat, durch diesen Pfad. Ohne Pfad wird die Adresse der Anfrage unverändert weitergegeben.

    locationproxy_passEingehende AnfragePfad an das Backend
    /app/http://127.0.0.1:3000/app/login/app/login
    /app/http://127.0.0.1:3000//app/login/login
    /alt/http://127.0.0.1:3000/neu//alt/seite/neu/seite
    /apphttp://127.0.0.1:3000//app/login//login (falsch)
    Nginx
    # 1) KEIN Pfad in proxy_pass: Die Adresse wird unverändert weitergegeben
    #    /app/login  ->  /app/login
    location /app/ {
        proxy_pass http://127.0.0.1:3000;
    }
    
    # 2) proxy_pass endet mit "/": Das passende Präfix wird entfernt
    #    /api/liste  ->  /liste
    location /api/ {
        proxy_pass http://127.0.0.1:3001/;
    }
    
    # 3) proxy_pass enthält einen anderen Pfad: Das Präfix wird dadurch ersetzt
    #    /alt/seite  ->  /neu/seite
    location /alt/ {
        proxy_pass http://127.0.0.1:3000/neu/;
    }

    Als Regel gilt: Lassen Sie location und den Pfad in proxy_pass gleich enden – beide mit Schrägstrich oder gar kein Pfad in proxy_pass. Ist Ihre Anwendung für den Betrieb unter einem Unterpfad (z. B. /app/) eingerichtet, behalten Sie das Präfix bei; geht sie davon aus, im Wurzelverzeichnis zu laufen, entfernen Sie es. In location-Blöcken, die über einen regulären Ausdruck definiert sind, darf proxy_pass keinen Pfad enthalten; Nginx meldet beim Konfigurationstest einen Fehler.

    Vergleichsschema: Ohne Schrägstrich am Ende von proxy_pass wird der Pfad unverändert weitergegeben, mit Schrägstrich wird das location-Präfix entfernt : Vergrößern
  4. Die nötigen Header weiterreichen

    Nginx sendet die Anfrage in eigenem Namen erneut an das Backend. Ohne zusätzliche Einstellungen sieht die Anwendung die IP-Adresse von Nginx statt der des Besuchers, und der Host-Header enthält die Adresse aus proxy_pass. Diese vier Header übermitteln der Anwendung die fehlenden Informationen:

    Nginx
    proxy_pass http://127.0.0.1:3000;
    
    # Der Domainname, den der Besucher aufgerufen hat
    proxy_set_header Host              $host;
    # IP-Adresse des Clients, der sich mit Nginx verbunden hat
    proxy_set_header X-Real-IP         $remote_addr;
    # Adressen, über die die Anfrage lief (wird an die Liste angehängt)
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    # Vom Besucher verwendetes Schema: http oder https
    proxy_set_header X-Forwarded-Proto $scheme;
    • Host: der Domainname, den der Besucher aufgerufen hat. Die Anwendung nutzt ihn, um Links zu erzeugen und mehrere Domains zu unterscheiden.
    • X-Real-IP: die IP-Adresse des Clients, der sich mit Nginx verbunden hat.
    • X-Forwarded-For: die Liste der Adressen, über die die Anfrage gelaufen ist. $proxy_add_x_forwarded_for hängt die verbindende Adresse an die vom Client gesendete Liste an.
    • X-Forwarded-Proto: das vom Besucher verwendete Schema (http oder https).

    Achtung: proxy_set_header-Direktiven werden von der übergeordneten Ebene nur dann geerbt, wenn auf der aktuellen Ebene überhaupt kein proxy_set_header steht. Fügen Sie in einer location einen einzelnen Header hinzu, gelten die auf server-Ebene geschriebenen in diesem Block nicht mehr; Sie müssen alle wiederholen.

  5. WebSocket-Unterstützung ergänzen

    Funktionen wie Live-Chat, Benachrichtigungen oder Echtzeit-Dashboards nutzen WebSocket. Ein WebSocket beginnt als gewöhnliche HTTP-Anfrage, die über den Upgrade-Header zu einer dauerhaften Verbindung hochgestuft wird. Diese Header passieren einen Proxy nicht von selbst; sie müssen ausdrücklich weitergereicht werden, und Nginx muss mit dem Backend HTTP/1.1 sprechen.

    Nginx
    # Einmal auf http-Ebene definieren (außerhalb des server-Blocks)
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }
    
    server {
        listen 80;
        server_name beispiel.de;
    
        location / {
            proxy_pass http://127.0.0.1:3000;
    
            # HTTP/1.1 und Upgrade-Header für WebSocket
            proxy_http_version 1.1;
            proxy_set_header Upgrade    $http_upgrade;
            proxy_set_header Connection $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;
    
            # Eine untätige WebSocket-Verbindung wird nach dieser Zeit geschlossen
            proxy_read_timeout 300s;
        }
    }

    Der map-Block gehört auf die http-Ebene (außerhalb des server-Blocks): Er sorgt dafür, dass Connection: upgrade gesendet wird, wenn der Client ein Upgrade verlangt hat, und andernfalls Connection: close. So funktioniert dieselbe location für normale Anfragen und für WebSocket.

    Kommen über eine WebSocket-Verbindung für die Dauer von proxy_read_timeout keine Daten, schließt Nginx sie. Erhöhen Sie den Wert oder lassen Sie die Anwendung in regelmäßigen Abständen einen „Ping“ senden.

    Schema: Die WebSocket-Upgrade-Anfrage wird über Nginx mit den Headern Upgrade und Connection an die Anwendung weitergereicht, die Verbindung bleibt offen : Vergrößern
  6. Timeouts und Body-Größe einstellen

    DirektiveWas legt sie fest?Standard
    proxy_connect_timeoutWartezeit für den Verbindungsaufbau zum Backend60s
    proxy_send_timeoutLängste Wartezeit zwischen zwei Schreibvorgängen beim Senden der Anfrage an das Backend60s
    proxy_read_timeoutLängste Wartezeit zwischen zwei Lesevorgängen beim Lesen der Antwort vom Backend60s
    client_max_body_sizeObergrenze für den Anfrage-Body, den ein Client senden darf (z. B. Datei-Upload)1m
    Nginx
    # Upload-Grenze (Standard 1m); bei Überschreitung folgt 413
    client_max_body_size 20m;
    
    location / {
        proxy_pass http://127.0.0.1:3000;
    
        proxy_connect_timeout 5s;    # Verbindungsaufbau zum Backend
        proxy_send_timeout    60s;   # Senden der Anfrage an das Backend
        proxy_read_timeout    60s;   # Warten auf die Antwort des Backends
    }
    
    # Längere Wartezeit nur für die lang laufende Berichtsadresse
    location /berichte/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_read_timeout 180s;
    }

    Die Lese- und Sende-Timeouts messen nicht die Gesamtdauer, sondern die Stille zwischen zwei Vorgängen. Sendet die Anwendung 60 Sekunden lang nichts, erhält der Besucher den Fehler 504. Wird die Upload-Grenze überschritten, antwortet Nginx mit 413; denken Sie daran, die Upload-Grenze der Anwendung selbst auf denselben Wert zu setzen. Halten Sie die Zeiten nicht länger als nötig: Eine eigene location für bestimmte Adressen wie lange Berichte oder Exporte ist besser, als die Grenze für die ganze Website anzuheben. Ausführlich behandelt diese Fehler die Anleitung 502, 504 und andere Nginx-Fehler.

  7. Konfiguration testen und neu laden

    Nginx liest seine Konfigurationsdateien nicht von selbst neu ein. Testen Sie zuerst die Syntax und laden Sie die Konfiguration neu (Reload), wenn der Test erfolgreich war. Ein Reload trennt keine offenen Verbindungen; ist die Konfiguration fehlerhaft, läuft Nginx mit den alten Einstellungen weiter.

    Bash
    # 1) Konfiguration testen
    sudo nginx -t
    
    # 2) Bei erfolgreichem Test neu laden (Verbindungen bleiben bestehen)
    sudo systemctl reload nginx
    
    # Dasselbe auf Systemen ohne systemd:
    sudo nginx -s reload

    nginx -t prüft nur die Syntax und den Kontext der Direktiven, nicht aber, ob das Backend erreichbar ist. Rufen Sie die Website deshalb anschließend mit curl oder im Browser auf.

    Ablaufschema: Datei bearbeiten, mit nginx -t testen, neu laden, mit curl prüfen, Logs kontrollieren : Vergrößern
  8. Der Anwendung beibringen, dem Proxy zu vertrauen

    Auch wenn Nginx die Header sendet, verwendet die Anwendung sie nicht automatisch. Die meisten Anwendungs-Frameworks haben dafür eine Einstellung namens „Trusted Proxies“ (vertrauenswürdige Proxys): Dort tragen Sie die Adresse Ihres Reverse Proxys ein (127.0.0.1, wenn er auf demselben Server läuft); das Framework berücksichtigt die X-Forwarded-*-Header dann nur bei Anfragen von dieser Adresse. Name und Ort der Einstellung hängen vom verwendeten Framework ab; suchen Sie in dessen Dokumentation nach „Proxy“.

    Typische Symptome, wenn diese Einstellung fehlt: In den Logs erscheinen alle Besucher als 127.0.0.1, eine IP-basierte Ratenbegrenzung zählt alle als eine Person, die Anwendung hält sich für http und gerät in eine endlose Weiterleitungsschleife oder erzeugt Links mit http://.

    Sicherheitsregel: X-Forwarded-*-Header kann jeder senden. Vertrauen Sie ihnen nur, wenn die Anfrage von Ihrem eigenen Reverse Proxy kommt; vermeiden Sie Einstellungen der Art „allen Adressen vertrauen“. Andernfalls kann ein Angreifer mit einem gefälschten Header IP-Beschränkungen und Ratenbegrenzungen umgehen. In einer PHP-Anwendung ohne Framework sieht dieselbe Logik so aus:

    PHP
    <?php
    // Nur die Adressen Ihres eigenen Reverse Proxys (127.0.0.1, wenn Nginx auf demselben Server läuft)
    $guvenilenProxyler = array('127.0.0.1');
    
    $uzakAdres = $_SERVER['REMOTE_ADDR'] ?? '';
    $istemciIp = $uzakAdres;
    $httpsMi = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
    
    // Die Header werden nur gelesen, wenn die Anfrage von einem vertrauenswürdigen Proxy kam
    if (in_array($uzakAdres, $guvenilenProxyler, true)) {
        $gercekIp = $_SERVER['HTTP_X_REAL_IP'] ?? '';
        if (filter_var($gercekIp, FILTER_VALIDATE_IP) !== false) {
            $istemciIp = $gercekIp;
        }
        $httpsMi = ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https';
    }

    Das Beispiel liest den Header X-Real-IP, weil Nginx ihn bei jeder Anfrage mit der tatsächlich gesehenen Adresse überschreibt. X-Forwarded-For dagegen hängt an den vom Client gesendeten Wert an; die erste Adresse der Liste kann gefälscht sein, verlässlich ist die letzte, von Ihrem Proxy hinzugefügte Adresse.

    Vergleich: Ohne weitergereichte Header sieht die Anwendung 127.0.0.1 und http; mit Headern und vertrauenswürdigem Proxy sieht sie die echte IP und https : Vergrößern

Vollständige Beispielkonfiguration

Die folgende Datei fasst alle bisherigen Schritte zusammen. Ersetzen Sie die Domain und die Adresse der Anwendung durch Ihre eigenen.

Nginx
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    server_name beispiel.de www.beispiel.de;

    # Obergrenze für den Anfrage-Body (Datei-Uploads)
    client_max_body_size 20m;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;

        # Damit die Anwendung die echte Domain, die IP und das Schema sieht
        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;

        # WebSocket
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        # Timeouts
        proxy_connect_timeout 5s;
        proxy_send_timeout    60s;
        proxy_read_timeout    60s;
    }
}

Um HTTPS zu ergänzen, fahren Sie mit der Anleitung HTTPS in Nginx fort. Sobald HTTPS aktiv ist, wird die Variable $scheme von selbst zu https; die Header-Zeilen müssen Sie nicht ändern. Für die Verteilung auf mehrere Anwendungsserver siehe die Anleitung zur Lastverteilung.

Häufige Fehler

  • Unpassende Schrägstriche: location /api wird mit proxy_pass …/ kombiniert; beim Backend kommt //pfad an oder die Anwendung antwortet mit 404.
  • Host-Header vergessen: Die Anwendung erzeugt Links mit 127.0.0.1:3000 oder zeigt die falsche Website.
  • Einen einzelnen Header in einer location schreiben: Die übrigen proxy_set_header-Zeilen der übergeordneten Ebene werden in diesem Block nicht geerbt.
  • WebSocket vergessen: Die Seite lädt, aber Live-Funktionen arbeiten nicht; in der Browserkonsole steht ein Verbindungsfehler.
  • Das Backend zum Internet offen lassen: Lauscht die Anwendung auf 0.0.0.0, lassen sich alle Grenzen und Zugriffsregeln in Nginx umgehen.
  • Neustart ohne Test: Ein Neustart (Restart) mit fehlerhafter Konfiguration kann dazu führen, dass Nginx gar nicht mehr startet. Erst nginx -t, dann neu laden.
  • In der Anwendung allen vertrauen: Wer die Liste der vertrauenswürdigen Proxys auf „alle Adressen“ setzt, akzeptiert auch gefälschte Header.

Die Einrichtung überprüfen

  • Rufen Sie die Anwendung direkt vom Server aus auf: Kommt eine Antwort, läuft das Backend.
  • Stellen Sie dieselbe Anfrage mit dem Domainnamen über Nginx: Ist die Antwort gleich, funktioniert der Proxy.
  • Prüfen Sie von außerhalb des Servers, dass http://server-ip:3000 nicht erreichbar ist.
  • Kontrollieren Sie im Log der Anwendung, dass als Besucher-IP die echte Adresse und nicht 127.0.0.1 erscheint.
  • Bei Problemen sehen Sie in das Nginx-Fehlerlog; in den meisten Installationen ist das /var/log/nginx/error.log.
Bash
# Vom Server aus: Antwortet die Anwendung direkt?
curl -I http://127.0.0.1:3000/

# Über Nginx: Kommt mit dem Domainnamen dieselbe Antwort?
curl -I http://beispiel.de/

# Bei Fehlern die letzten Logzeilen (Pfad in den meisten Installationen)
sudo tail -n 50 /var/log/nginx/error.log

Häufige Fragen

Soll am Ende von proxy_pass ein Schrägstrich stehen?

Das hängt davon ab, unter welchem Pfad Ihre Anwendung die Anfrage erwartet. Mit Schrägstrich (oder einem anderen Pfad) ersetzt Nginx das von der location erfasste Präfix durch diesen Pfad; ohne gibt es die Adresse unverändert weiter. Im einfachen Fall, in dem Sie die ganze Website mit „location /“ weiterleiten, liefern beide dasselbe Ergebnis.

Warum sieht meine Anwendung alle Besucher als 127.0.0.1?

Weil nicht der Besucher, sondern Nginx die Verbindung aufbaut. Reichen Sie in Nginx die Header X-Real-IP und X-Forwarded-For weiter und tragen Sie in der Anwendung die Adresse Ihres Reverse Proxys als vertrauenswürdigen Proxy ein.

Was ist der Unterschied zwischen Reload und Restart?

Ein Reload übernimmt die Konfiguration, ohne offene Verbindungen zu trennen; ist die Konfiguration fehlerhaft, läuft Nginx mit den alten Einstellungen weiter. Ein Restart stoppt und startet Nginx; mit fehlerhafter Konfiguration startet es möglicherweise gar nicht. Für alltägliche Änderungen genügt ein Reload.

Was ändert sich, wenn die Anwendung auf einem anderen Server läuft?

In proxy_pass tragen Sie die interne Netzwerkadresse dieses Servers ein (z. B. http://10.0.0.5:3000). Binden Sie die Anwendung an die interne Adresse, öffnen Sie den Port in der Firewall nur für den Nginx-Server und tragen Sie dessen interne Adresse in die Liste der vertrauenswürdigen Proxys der Anwendung ein.

Muss auch der Verkehr zwischen Nginx und der Anwendung verschlüsselt sein?

Laufen beide auf demselben Server, verlässt der Verkehr den Server nicht; HTTPS in Nginx zu beenden (SSL-/TLS-Terminierung) ist eine verbreitete und ausreichende Lösung. Führt der Weg über ein Netz, dem Sie nicht vertrauen, sollten Sie auch die Verbindung zum Backend verschlüsseln.

BYK Yazılım Support-Team
Diese Anleitung wird vom Support-Team von BYK Yazılım erstellt und regelmäßig überprüft. Letzte Aktualisierung: 04.10.2026.

Verwandte Anleitungen

Sprechen wir über die Infrastruktur Ihrer Website

BYK Yazılım entwickelt Unternehmenswebsites. Schreiben Sie uns bei Fragen zu Ihrer Website.

Kontakt aufnehmen Unternehmenswebsite