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 und PHP-FPM: So laufen PHP-Websites mit Nginx

Bei einer Website, die mit Apache läuft, funktioniert PHP meist „von selbst“, denn Apache kann PHP als Modul im eigenen Prozess ausführen. Bei Nginx ist das anders: Nginx kann keinen PHP-Code ausführen. Stattdessen übergibt es die Anfrage an PHP-FPM (FastCGI Process Manager), das als eigener Dienst auf PHP-Anfragen wartet, nimmt die Antwort entgegen und sendet sie an den Besucher.

Die Sprache, in der sich beide verständigen, ist ein Protokoll namens FastCGI. Es gibt also zwei getrennte Programme, zwei getrennte Konfigurationen und eine Verbindung dazwischen. Die meisten Probleme mit PHP-Websites unter Nginx („502 Bad Gateway“, leere Seite, PHP-Datei wird heruntergeladen) gehen auf eine Einstellung an einem Ende dieser Verbindung zurück. Diese Anleitung erklärt zuerst, wie das Zusammenspiel funktioniert, und führt dann Schritt für Schritt durch die richtige Konfiguration. Wenn Nginx für Sie neu ist, werfen Sie zuerst einen Blick in die Anleitung Was ist Nginx?

Kurz gefasst

  • Nginx führt kein PHP aus; .php-Anfragen gehen per FastCGI an PHP-FPM.
  • Die Adresse in fastcgi_pass muss dem listen-Wert im PHP-FPM-Pool entsprechen.
  • try_files verhindert, dass nicht vorhandene Dateien an PHP übergeben werden.
  • Fehlt der Socket oder stimmen seine Rechte nicht, sieht der Besucher 502.

Das brauchen Sie

  • Administratorrechte (sudo) auf dem Server
  • Installiertes Nginx und PHP-FPM-Paket
  • Die Nginx-Konfigurationsdatei der Website und eine Sicherung davon
  • Zugriff auf die Protokolle von Nginx und PHP-FPM

Hinweis

Die Socket- und Dateipfade in dieser Anleitung sind Beispiele. Socket-Pfad, Dienstname und Konfigurationsordner von PHP-FPM hängen von der Distribution und der PHP-Version ab; prüfen Sie die Werte Ihres eigenen Servers wie in Schritt 2 beschrieben.

Auf dieser Seite

Nginx und PHP-FPM Schritt für Schritt konfigurieren

  1. Den Ablauf verstehen: Wer macht was?

    Trifft eine Anfrage ein, ist die Arbeit so verteilt:

    • Statische Dateien (Bilder, CSS, JavaScript): Nginx liest sie von der Festplatte und sendet sie direkt; PHP-FPM ist gar nicht beteiligt.
    • PHP-Anfragen: Nginx übergibt die Anfrage zusammen mit der Angabe, welche Datei auszuführen ist, an PHP-FPM. PHP-FPM führt die Datei mit einem seiner wartenden Worker-Prozesse aus und gibt die Ausgabe an Nginx zurück.

    Nginx und PHP-FPM sprechen auf einem von zwei Wegen miteinander:

    • Unix-Socket: Eine besondere Datei auf der Festplatte (z. B. /run/php/php-fpm.sock). Nur Prozesse auf demselben Rechner können ihn nutzen; der Zugriff wird über Dateirechte gesteuert.
    • TCP-Adresse: Eine Adresse mit Port wie 127.0.0.1:9000. Dieser Weg ist nötig, wenn PHP-FPM auf einem anderen Rechner oder in einem Container läuft.

    Liegen beide auf demselben Rechner, ist der Unix-Socket die übliche Wahl; wofür Sie sich auch entscheiden, auf beiden Seiten muss derselbe Wert stehen.

    Schema: Die Browseranfrage erreicht Nginx; statische Dateien liefert Nginx aus, PHP-Anfragen gehen per FastCGI über einen Socket an den PHP-FPM-Pool : Vergrößern
  2. Prüfen, ob PHP-FPM läuft und wo es lauscht

    Stellen Sie zuerst sicher, dass der PHP-FPM-Dienst läuft, und suchen Sie dann in der Pool-Datei die Zeile listen. Sie zeigt den Socket oder die Adresse, mit der sich Nginx verbinden wird.

    Bash
    # Läuft PHP-FPM? (der Dienstname hängt von der Distribution ab)
    systemctl status php-fpm           # RHEL, AlmaLinux und verwandte Systeme
    systemctl status 'php*-fpm'        # Debian, Ubuntu: der Name enthält die Version
    
    # Auf welchem Socket oder welcher Adresse lauscht der Pool?
    sudo grep -R "^listen" /etc/php-fpm.d/ /etc/php/ 2>/dev/null
    
    # Gibt es die Socket-Datei, und wie lauten Besitzer und Rechte?
    ls -l /run/php/ /run/php-fpm/ 2>/dev/null

    Dienstname und Pfade hängen von der Distribution ab: Unter Debian und Ubuntu enthalten Dienstname und Pfade die PHP-Version (z. B. ein Socket mit Versionsnummer unter /run/php/, Pool-Dateien unter /etc/php/<Version>/fpm/pool.d/); unter RHEL, AlmaLinux und verwandten Systemen heißt der Dienst meist php-fpm, der Pool-Ordner ist /etc/php-fpm.d/ und der Socket liegt unter /run/php-fpm/. Hosting-Panels können eigene Pfade verwenden. Raten Sie nicht; verwenden Sie genau das, was in der Zeile listen steht.

  3. PHP-Anfragen im server-Block an PHP-FPM leiten

    Der folgende server-Block zeigt den Grundaufbau für eine Website, die mit PHP läuft.

    Nginx
    server {
        listen 80;
        server_name beispiel.de www.beispiel.de;
    
        root /var/www/beispiel.de/public;
        index index.php index.html;
    
        location / {
            try_files $uri $uri/ =404;
        }
    
        location ~ \.php$ {
            # Nicht an PHP übergeben, wenn die Datei nicht auf der Festplatte liegt
            try_files $uri =404;
    
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    
            # Der Socket-Pfad hängt von der Distribution ab; er muss "listen" im Pool entsprechen
            fastcgi_pass unix:/run/php/php-fpm.sock;
            # Für einen Pool, der über TCP lauscht: fastcgi_pass 127.0.0.1:9000;
        }
    }

    Die Bedeutung Zeile für Zeile:

    • index index.php index.html; Legt fest, welche Datei gesucht wird, wenn ein Ordner angefragt wird (z. B. /). Steht index.php nicht in der Liste, öffnet sich die Startseite nicht oder es kommt 403 zurück.
    • try_files in location /: Ist die angefragte Adresse eine echte Datei oder ein Ordner, wird sie ausgeliefert; andernfalls kommt 404 zurück.
    • location ~ \.php$: Erfasst Anfragen, deren Adresse auf .php endet.
    • fastcgi_pass: Die PHP-FPM-Adresse, an die die Anfrage übergeben wird. Für einen Unix-Socket wird der Pfad mit dem Präfix unix: geschrieben, für TCP in der Form 127.0.0.1:9000.

    Bei Anwendungen, die alle Anfragen in einer einzigen index.php entgegennehmen (die meisten Frameworks und fertigen Content-Management-Systeme), sieht der Block location / etwas anders aus: Wird keine Datei gefunden, geht die Anfrage statt mit 404 zu enden an index.php.

    Nginx
    # Inhalt des Blocks "location /": Gibt es weder Datei noch Ordner, geht die Anfrage an index.php
    try_files $uri $uri/ /index.php?$query_string;

    Fehlt dieser Block, öffnet sich die Startseite, die Unterseiten liefern aber 404. Bei Apache erledigen das die Rewrite-Regeln in der .htaccess; zur Übertragung siehe die Anleitung zum Umstieg von Apache auf Nginx.

    Ablaufschema: Anfrage trifft ein, location wird gewählt, try_files prüft, ob die Datei existiert, fastcgi_pass übergibt an PHP-FPM, die Antwort kommt zurück : Vergrößern
  4. fastcgi_params und SCRIPT_FILENAME richtig angeben

    Nginx teilt PHP-FPM nicht nur mit, dass „eine Anfrage vorliegt“; es sendet die Einzelheiten der Anfrage als FastCGI-Parameter: Anfragemethode, Query-String, IP-Adresse des Besuchers, Servername und Ähnliches. Auf der PHP-Seite erscheinen sie im Array $_SERVER.

    • include fastcgi_params; Bindet die mit Nginx gelieferte Datei ein, die diese Standardparameter definiert.
    • SCRIPT_FILENAME ist der Parameter, der PHP-FPM mit vollständigem Pfad mitteilt, welche Datei auszuführen ist. Der Wert $document_root$fastcgi_script_name verbindet den mit root angegebenen Ordner mit dem Namen der angefragten Datei.

    Die Datei fastcgi_params enthält die Zeile SCRIPT_FILENAME in der Regel nicht; deshalb steht sie im Beispiel gesondert. Die ebenfalls mit Nginx gelieferte Datei fastcgi.conf enthält diese Zeile; wenn Sie diese verwenden, müssen Sie die Zeile nicht ein zweites Mal schreiben. In den Paketen von Debian und Ubuntu gibt es zudem eine fertige Snippet-Datei, die diese Einstellungen bündelt. Was Sie auch verwenden: Prüfen Sie, dass der Parameter einmal und richtig definiert ist.

    Fehlt SCRIPT_FILENAME oder ist der Wert falsch, findet PHP-FPM die Datei nicht: Der Besucher sieht eine leere Seite oder die Antwort „File not found.“. Die häufigste Ursache ist eine root-Direktive, die auf den falschen Ordner zeigt, oder ein abweichendes root innerhalb der location.

  5. Nicht vorhandene Dateien nicht an PHP übergeben

    Die erste Zeile des PHP-Blocks im Beispiel, try_files $uri =404;, ist eine Schutzmaßnahme. Existiert die angefragte .php-Datei nicht auf der Festplatte, übergibt Nginx die Anfrage gar nicht erst an PHP-FPM, sondern gibt sofort 404 zurück.

    Warum ist das wichtig? Ohne diese Prüfung erreicht eine .php-Adresse, die es in Wirklichkeit nicht gibt, PHP, und je nach PHP-Einstellung zur Pfadauflösung kann eine andere Datei als PHP ausgeführt werden. Gibt es auf Ihrer Website einen Bereich, in dem Nutzer Dateien hochladen können, kann das so weit gehen, dass eine hochgeladene Datei als Code ausgeführt wird. Die einzeilige Prüfung schließt diese Tür.

    • Die Prüfung funktioniert, wenn Nginx und PHP-FPM dasselbe Dateisystem sehen. Läuft PHP-FPM auf einem anderen Rechner oder in einem Container, sieht Nginx die Datei nicht und jede Anfrage endet mit 404; in dieser Anordnung muss die Prüfung auf der PHP-Seite erfolgen.
    • Als zusätzliche Schicht begrenzt die Einstellung security.limit_extensions im PHP-FPM-Pool, welche Dateiendungen als PHP ausgeführt werden dürfen; lockern Sie diese Grenze nicht.
  6. Die Pool-Einstellungen kennenlernen

    PHP-FPM verwaltet seine Worker-Prozesse in Gruppen, die Pools genannt werden. Jeder Pool hat seine eigene Listen-Adresse, seinen eigenen Benutzer und seine eigenen Prozessgrenzen. Liegen mehrere Websites auf demselben Server, erschwert ein eigener Pool mit eigenem Benutzer je Website, dass ein Problem in einer Website die Dateien einer anderen erreicht.

    PHP-FPM
    ; Pool-Datei (z. B. www.conf); ihr Pfad hängt von der Distribution ab
    [beispiel]
    user = beispiel
    group = beispiel
    
    ; Muss mit fastcgi_pass in Nginx übereinstimmen
    listen = /run/php/php-fpm.sock
    
    ; Besitzer und Rechte des Sockets: Der Nginx-Benutzer muss zugreifen können
    ; (Debian, Ubuntu: www-data; RHEL, AlmaLinux: nginx)
    listen.owner = www-data
    listen.group = www-data
    listen.mode = 0660
    
    ; Prozessverwaltung (die Zahlen sind ein Syntaxbeispiel, keine Empfehlung)
    pm = dynamic
    pm.max_children = 10
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    EinstellungWas legt sie fest?
    listenDen Socket oder die Adresse, auf der PHP-FPM lauscht. Muss mit fastcgi_pass in Nginx übereinstimmen.
    user, groupUnter welchem Benutzer der PHP-Code läuft. Lese- und Schreibrechte auf Dateien richten sich nach diesem Benutzer.
    pmDen Modus der Prozessverwaltung: static (feste Zahl von Prozessen), dynamic (je nach Last zwischen Unter- und Obergrenze) oder ondemand (Start bei eintreffenden Anfragen, Ende bei Leerlauf).
    pm.max_childrenDie Obergrenze der gleichzeitig laufenden Worker-Prozesse; also die Zahl der PHP-Anfragen, die gleichzeitig verarbeitet werden können.

    Für pm.max_children gibt es keine Zahl, die für alle passt. Jeder Worker-Prozess belegt Arbeitsspeicher; ist die Grenze zu hoch, geht dem Server bei hoher Last der Speicher aus, ist sie zu niedrig, warten Anfragen in der Warteschlange und im PHP-FPM-Protokoll erscheint eine Warnung, dass die Grenze erreicht wurde. Der richtige Wert wird durch Messen ermittelt, anhand des freien Arbeitsspeichers des Servers und des Speicherbedarfs Ihrer Anwendung je Prozess. Lesen Sie die Zahlen im Beispiel als Syntaxbeispiel, nicht als Empfehlung.

    Schema: die grundlegenden Einstellungen eines PHP-FPM-Pools; listen, user und group, die pm-Modi und pm.max_children : Vergrößern
  7. Socket-Berechtigungen und den Fehler 502 prüfen

    „502 Bad Gateway“ bedeutet, dass Nginx vom dahinterliegenden Dienst keine gültige Antwort erhalten hat. Bei PHP-Websites ist die häufigste Ursache, dass Nginx keine Verbindung zu PHP-FPM herstellen kann. Raten Sie die Ursache nicht; das Nginx-Fehlerprotokoll nennt sie ausdrücklich.

    Meldung im ProtokollMögliche UrsacheWo nachsehen?
    No such file or directoryDie Socket-Datei fehlt: PHP-FPM läuft nicht oder der Pfad in fastcgi_pass ist falsch (z. B. PHP wurde aktualisiert, der Socket-Name hat sich geändert)Dienststatus; stimmen listen und fastcgi_pass überein?
    Permission deniedDer Socket existiert, aber der Benutzer, unter dem Nginx läuft, darf nicht darauf zugreifenlisten.owner, listen.group, listen.mode
    Connection refusedAuf der TCP-Adresse lauscht kein DienstDienststatus; Adresse und Port

    Da ein Unix-Socket eine Datei ist, hat er Berechtigungen. Im Pool legen listen.owner und listen.group den Besitzer des Sockets fest, listen.mode seine Rechte. Der Benutzer, unter dem die Nginx-Worker-Prozesse laufen (je nach Distribution meist www-data oder nginx), muss lesend und schreibend auf diesen Socket zugreifen können. Den Socket für alle zu öffnen (0666) „löst“ das Problem zwar, erlaubt aber jedem Benutzer des Servers, Anfragen an PHP-FPM zu senden; setzen Sie stattdessen Besitzer und Gruppe richtig.

    Zeigt die Seite erst nach einiger Wartezeit einen Fehler (504) oder tritt 502 nur bei hoher Last auf, liegt die Ursache nicht in der Verbindung, sondern in der Langsamkeit auf der PHP-Seite oder in der Prozessgrenze. Zur ausführlichen Diagnose siehe die Anleitung zu den Fehlern 502 und 504.

    Schema: drei Meldungen im Nginx-Fehlerprotokoll beim Fehler 502 und ihre Bedeutung; Socket fehlt, keine Berechtigung, Verbindung abgelehnt : Vergrößern
  8. PHP-Ausführung im Upload-Ordner abschalten

    Es gibt keinen Grund, dass in dem Ordner, in den Besucher oder Administratoren Dateien hochladen (z. B. /upload/), PHP ausgeführt wird. Selbst wenn Ihre Upload-Prüfung eine Lücke hat, kann eine hochgeladene Schaddatei nicht ausgeführt werden, wenn Dateien aus diesem Ordner nicht an PHP-FPM übergeben werden. Das ist eine zweite Verteidigungslinie, die allein nicht ausreicht, aber wirksam ist.

    Nginx
    # Muss VOR dem allgemeinen Block "location ~ \.php$" stehen
    location ~* ^/upload/.*\.(php|phtml|phar)$ {
        return 403;
    }

    Achten Sie auf zwei Punkte: Passen Sie den Ordnernamen an Ihre eigene Website an, und schreiben Sie diesen Block vor den allgemeinen Block location ~ \.php$. Nginx probiert location-Blöcke mit regulären Ausdrücken in der Reihenfolge der Datei und verwendet den ersten Treffer; bei umgekehrter Reihenfolge greift die Regel nicht. Zur Upload-Sicherheit insgesamt siehe die Anleitung zur Sicherheit beim Datei-Upload.

    Vergleich: Ist PHP im Upload-Ordner aktiv, kann eine hochgeladene Datei ausgeführt werden; ist es abgeschaltet, geht die Anfrage nicht an PHP-FPM und es kommt 403 zurück : Vergrößern
  9. Testen, neu laden, überprüfen

    Prüfen Sie nach den Änderungen zuerst die Konfiguration und laden Sie dann den betreffenden Dienst neu. Haben Sie die Nginx-Datei geändert, laden Sie Nginx neu; haben Sie die Pool-Datei geändert, laden Sie PHP-FPM neu.

    Bash
    # Nginx-Konfiguration prüfen und neu laden
    sudo nginx -t
    sudo systemctl reload nginx
    
    # Wurde die Pool-Datei geändert, PHP-FPM neu laden (der Dienstname hängt von der Distribution ab)
    sudo systemctl reload php-fpm
    
    # Bei Problemen die letzten Fehlereinträge ansehen
    sudo tail -n 50 /var/log/nginx/error.log

    Testen Sie anschließend im Browser: Öffnet sich die Startseite, öffnet sich eine Unterseite, liefert eine nicht vorhandene .php-Adresse 404, liefert eine .php-Adresse im Upload-Ordner 403? Wird eine PHP-Datei heruntergeladen, statt ausgeführt zu werden, oder erscheint ihr Quelltext auf dem Bildschirm, erreicht die Anfrage den PHP-Block gar nicht: Prüfen Sie, ob der Block location ~ \.php$ im richtigen server steht und ob neu geladen wurde.

Häufige Symptome und ihre Ursachen

SymptomMögliche Ursache
502 Bad GatewayPHP-FPM läuft nicht, der Socket-Pfad ist falsch oder die Socket-Rechte geben Nginx keinen Zugriff
Leere Seite oder „File not found.“SCRIPT_FILENAME fehlt oder ist falsch; root zeigt auf den falschen Ordner
PHP-Datei wird heruntergeladenEs gibt keinen location-Block für PHP oder die Anfrage landet in einem anderen Block
Startseite öffnet sich, Unterseiten liefern 404Die try_files-Weiterleitung an den Front-Controller (index.php) fehlt
403 auf der Startseiteindex.php fehlt in der Direktive index oder die Ordnerrechte erlauben Nginx das Lesen nicht
413 beim Hochladen einer DateiDie Grenze von Nginx für den Anfragekörper (client_max_body_size, Standardwert 1m) wird überschritten; die Upload-Grenzen von PHP gelten zusätzlich

In jedem Fall sind die Protokolle die erste Anlaufstelle: das Nginx-Fehlerprotokoll (meist /var/log/nginx/error.log) und das PHP-FPM-Protokoll. Ihr Speicherort kann je nach Konfiguration abweichen.

Kurze Checkliste zur Sicherheit

  • Im PHP-Block steht try_files $uri =404;; nicht vorhandene Dateien gehen nicht an PHP.
  • In Upload-Ordnern ist die PHP-Ausführung abgeschaltet.
  • Die Socket-Rechte sind eng gefasst: Nur der Benutzer oder die Gruppe von Nginx hat Zugriff.
  • Lauscht PHP-FPM über TCP, dann nur auf 127.0.0.1 oder einer Adresse im internen Netz; es ist nicht aus dem Internet erreichbar.
  • Jede Website läuft in ihrem eigenen Pool und unter ihrem eigenen Benutzer; PHP-Prozesse laufen nicht als Administrator (root).
  • Der PHP-Benutzer kann nur in die benötigten Ordner schreiben.
  • Fehlerdetails werden ins Protokoll geschrieben, nicht dem Besucher angezeigt.

Für den Server insgesamt siehe die Anleitungen Nginx-Sicherheitseinstellungen und Server- und Hosting-Sicherheit.

Häufige Fragen

Unter Nginx wird meine PHP-Datei heruntergeladen statt ausgeführt. Warum?

Das bedeutet, dass die Anfrage nicht an PHP-FPM übergeben wird. Im server-Block der Website muss es einen location-Block geben, der die Endung .php erfasst und fastcgi_pass enthält. Ist der Block vorhanden, prüfen Sie, ob er im richtigen server steht, ob die Konfiguration getestet und neu geladen wurde und ob der Browser nicht eine alte Antwort aus dem Cache anzeigt.

Soll ich einen Unix-Socket oder 127.0.0.1:9000 verwenden?

Liegen Nginx und PHP-FPM auf demselben Rechner, ist der Unix-Socket die übliche Wahl; er öffnet keinen Netzwerkport, und der Zugriff wird über Dateirechte gesteuert. Läuft PHP-FPM auf einem anderen Rechner oder in einem Container, ist TCP erforderlich. Wofür Sie sich auch entscheiden: fastcgi_pass und listen im Pool müssen übereinstimmen.

Ich habe PHP aktualisiert, seitdem liefert die Website 502. Warum?

Bei manchen Distributionen enthalten die Namen der Socket-Datei und des Dienstes die PHP-Version. Ändert sich die Version, ändert sich auch der Socket-Pfad, während Nginx weiter versucht, sich mit dem alten Pfad zu verbinden. Suchen Sie den listen-Wert in der neuen Pool-Datei, passen Sie die Zeile fastcgi_pass entsprechend an, testen Sie und laden Sie neu.

Wie hoch sollte pm.max_children sein?

Einen Wert, der für alle passt, gibt es nicht. Er hängt vom verfügbaren Arbeitsspeicher des Servers und vom Speicherbedarf Ihrer Anwendung je Prozess ab. Ein zu hoher Wert erschöpft den Speicher, ein zu niedriger lässt Anfragen warten. Stellen Sie ihn ein, indem Sie auf Ihrem eigenen Server messen und die Warnungen im PHP-FPM-Protokoll beobachten.

Funktionieren meine .htaccess-Regeln von Apache mit PHP-FPM?

Nein. Die .htaccess ist Apache-spezifisch; weder Nginx noch PHP-FPM liest diese Datei. Regeln für Weiterleitungen, Zugriffsbeschränkungen und das Umschreiben von Adressen müssen in die Nginx-Konfiguration übertragen werden.

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