Was ist PHP-FPM | PHP-FPM installieren und einrichten

Testumgebung RHEL-FamilieAlmaLinux 9.8Apache 2.4 + PHP-FPM 8.3root-KontoGeprüft am 2026-10-26

PHP-FPM ist ein FastCGI-Prozessmanager: Vorab gestartete Worker-Prozesse nehmen die PHP-Anfragen entgegen, die ein Webserver weiterreicht, und bearbeiten sie. Auf einem AlmaLinux-9-Server mit Apache prüft diese Anleitung, ob es installiert ist und wie die Pools und Sockets je Website eingerichtet sind, und führt bis zur Konfigurationsprüfung und zur Statusabfrage mit echter Ausgabe.

Apache kann PHP auch direkt über mod_php ausführen, aber wenn du es an PHP-FPM übergibst, sind Webserver und PHP getrennt. Nginx kann PHP nicht direkt ausführen und gibt die Anfragen deshalb an einen FastCGI-Prozess wie PHP-FPM weiter. Darum lässt sich ein einziges PHP-FPM sowohl an Apache als auch an Nginx anbinden. Die Pool-Einstellungen und die Socket-Struktur weiter unten gelten unverändert auch, wenn du PHP-FPM mit Nginx verbindest.

1️⃣ Was PHP-FPM ist: der Unterschied zwischen CGI und FastCGI

CGI (Common Gateway Interface) ist das Standardverfahren, mit dem ein Webserver ein externes Programm ausführt, um dynamische Inhalte zu erzeugen, und es startet das Programm bei jeder eingehenden Anfrage neu. Der Aufwand, für jede Anfrage einen Prozess zu erzeugen und wieder zu entfernen, summiert sich, sodass der Server bei steigendem Zugriff immer langsamer antwortet.

FastCGI beseitigt diesen Aufwand, indem es das Programm vorab startet und die Anfragen nacheinander bearbeitet. Das ist der Unterschied zwischen einem Computer, den du bei jeder Nutzung ein- und ausschaltest, und einem Computer, der schon läuft und sofort benutzt werden kann. PHP-FPM (FastCGI Process Manager) ist der Manager, der PHP über FastCGI betreibt, und ist seit PHP 5.3.3 in PHP enthalten.

PHP-FPM startet für jeden Pool, also eine Gruppe von Workern, vorab die festgelegte Anzahl an Workern; ein freier Worker nimmt eine Anfrage entgegen, die der Webserver über den Socket weiterreicht, bearbeitet sie und wartet auf die nächste. Statische Dateien wie Bilder und CSS beantwortet der Webserver selbst, und nur PHP-Dateien gehen an PHP-FPM. Nur die Art, wie der Webserver Anfragen an den Socket übergibt, unterscheidet sich: Apache verwendet das Modul mod_proxy_fcgi, Nginx die Einstellung fastcgi_pass.

🧩 Wie CGI und PHP-FPM Anfragen bearbeiten
Erklär-Diagramm
⚙️ PHP-Ausführung
🌐 Webserver
🌐 ApacheNginx
📨 Anfrage 1 · index.php📨 Anfrage 2 · wp-login.php📨 Anfrage 3 · index.php
Statische Dateien (Bilder, CSS) beantwortet der Webserver selbst
Läuft bei jeder AnfrageFastCGI · Socket→
🧱 CGI-Prozesse
Anfrage 1Neuer Prozess → bearbeiten → beenden
Anfrage 2Neuer Prozess → bearbeiten → beenden
Anfrage 3Neuer Prozess → bearbeiten → beenden
Ist die Bearbeitung fertig, verschwindet auch der Prozess · die nächste Anfrage fängt von vorn an
🧰 PHP-FPM-Pool [siteuser]
Worker 1Anfrage 1
Worker 2Anfrage 2
Worker 3Anfrage 3
Worker 4Warten
Worker 5Warten
Vorab gestartete Worker nehmen Anfragen entgegen und warten danach auf die nächste
Wenn Apache PHP per CGI ausführt, startet es für jede Anfrage einen neuen PHP-Prozess und beendet ihn, sobald die Bearbeitung fertig ist, sodass sich der Aufwand für das Erzeugen der Prozesse mit mehr Anfragen summiert.
Nginx hat kein Modul, das CGI-Programme direkt ausführt, deshalb wird diese Kombination nicht verwendet; PHP wird über FastCGI an PHP-FPM übergeben.
Apache übergibt PHP-Anfragen mit mod_proxy_fcgi an den Socket, und ein vorab gestarteter PHP-FPM-Worker nimmt sie entgegen, bearbeitet sie und wartet auf die nächste.
Nginx übergibt Anfragen mit fastcgi_pass an denselben Socket, sodass der PHP-FPM-Pool auch bei einem anderen Webserver derselbe bleibt.

2️⃣ PHP-FPM installieren: Paket prüfen und mit dnf installieren

Wenn du PHP auf einem Server der RHEL-Familie mit dnf installiert hast, wurde das Paket php-fpm gleich mit installiert. Prüfe zuerst mit rpm, ob es installiert ist. Die Installation von PHP läuft genauso ab wie unter Rocky Linux APM installieren.

rpm -qa | grep php-fpm
php-fpm-8.3.36-1.module_php.8.3.el9.remi.x86_64

Ist die Ausgabe leer, ist es nicht installiert; dann installierst du es mit dnf.

dnf -y install php-fpm

Wenn die Installation fertig ist, prüfst du mit demselben rpm-Befehl noch einmal, ob der Paketname ausgegeben wird.

3️⃣ PHP-FPM konfigurieren: der Pool www.conf, der Socket sowie statischer und dynamischer Modus

Es gibt zwei Konfigurationsdateien: die Gesamtkonfiguration [/etc/php-fpm.conf] und die Pool-Konfiguration [/etc/php-fpm.d/www.conf]. Im Standard-Pool www.conf schaust du zuerst auf die Zeilen listen und pm, und die Werte direkt nach der Installation sind diese.

grep -E '^(listen|pm) ' /etc/php-fpm.d/www.conf
listen = /run/php-fpm/www.sock
pm = dynamic

listen ist der Ort, an den der Webserver Anfragen übergibt, und der Standardwert in Version 8.3 ist der Unix-Socket [/run/php-fpm/www.sock]. Der Standardwert älterer Versionen, [127.0.0.1:9000], nimmt Anfragen über einen TCP-Port entgegen. Innerhalb desselben Servers ist ein Socket leichter, weil der Verbindungsaufbau über einen Port entfällt, und mit listen.owner und listen.group kannst du den Zugriff wie Dateirechte einschränken.

🔲 Statischen und dynamischen Modus einstellen

pm legt fest, wie Worker gestartet werden, und du setzt es auf static, dynamic oder ondemand. Der statische Modus hält immer die in pm.max_children eingetragene Anzahl am Laufen, und die Einstellung unten hält 100 Worker.

pm = static
pm.max_children = 100

Der dynamische Modus ist der Standard und erhöht oder senkt die Zahl der Worker je nach Anfragemenge. Die Einstellung unten startet zu Beginn 12 Worker, hält 6 bis 18 freie Worker bereit und wächst auf höchstens 120.

pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18

Der Modus ondemand startet Worker nur, wenn eine Anfrage kommt, und beendet sie, sobald pm.process_idle_timeout verstrichen ist; er passt deshalb zu Websites mit wenig Zugriff, aber nicht zu Websites mit viel Zugriff.

Die drei Modi unterscheiden sich darin, wann Worker gestartet werden und wie ihre Zahl steigt und sinkt.

ModusWie Worker gestartet werdenPassende Websites
static (statisch)Hält immer die in pm.max_children eingetragene Anzahl am LaufenWebsites mit viel Zugriff
dynamic (dynamisch)Standard · steigt und sinkt je nach Anfragemenge innerhalb von pm.start_servers, pm.min_spare_servers und pm.max_spare_serversWebsites, deren Zugriffe schwanken
ondemandStartet nur, wenn eine Anfrage kommt, und endet, sobald pm.process_idle_timeout verstrichen istWebsites mit wenig Zugriff

max_children ergibt sich, wenn du den Serverspeicher durch den Speicher teilst, den ein Worker belegt. Auch wenn sich Warnungen zu [max_children] häufen, erhöhst du den Wert nicht gleich, sondern grenzt anhand der Logs zuerst ein, welche Anfragen die Worker gefüllt haben.

Arbeitsspeicher und Upload-Limit legst du in der php.ini fest, der Gesamtkonfiguration von PHP, und passt sie zusammen mit der Zahl der Worker an die Website an, die du betreibst.

memory_limit = 1024M
post_max_size = 128M
upload_max_filesize = 128M

Die drei Werte sind die Speichergrenze, die ein einzelnes PHP-Skript belegen darf, und die Dateigröße, die auf einmal hochgeladen werden kann; sie gelten erst nach einem Neustart von PHP-FPM.

🔲 Pools je Website-Konto einrichten

Bei mehreren Websites teilst du dir nicht eine einzige www.conf, sondern legst für jedes Konto eine eigene Pool-Datei an und trennst Ausführungskonto und Socket. Das PHP einer Website kann dann keine Dateien eines anderen Kontos lesen, und die Zahl der Worker wird je Website festgelegt.

vi /etc/php-fpm.d/siteuser.conf

In die Datei kommen der Pool-Name, das Ausführungskonto, der Socket-Pfad und die Zahl der Worker.

[siteuser]
user = siteuser
group = nobody
listen = /run/php-fpm/siteuser.sock
listen.owner = siteuser
listen.group = nobody
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
chdir = /home/siteuser/www

listen.owner und listen.group sind Besitzer und Gruppe der Socket-Datei, und PHP-FPM erstellt den Socket beim Start mit diesen Werten. Läuft der Webserver unter dem Konto nobody, trägst du bei listen.group nobody ein, bei dem Konto apache entsprechend apache, damit der Webserver den Socket öffnen kann.

listen.owner = siteuser
listen.group = nobody
listen.mode = 0660

Diese drei Zeilen stehen in jeder Pool-Datei, und nach einer Änderung der Werte musst du neu starten, damit der Socket mit den neuen Rechten erneut erstellt wird.

🔲 slowlog einstellen

slowlog ist eine Datei, die die Ausführungsstelle von Anfragen aufzeichnet, die länger als request_slowlog_timeout gedauert haben; bei dem Wert 0 wird nichts aufgezeichnet. Wenn du die Ursache langsamer Anfragen suchst, schaltest du es ein, indem du eine Sekundenangabe wie 3s setzt.

slowlog = /var/log/php-fpm/www-slow.log
request_slowlog_timeout = 0

In der aufgezeichneten Datei bleiben der Skriptpfad der langsamen Anfrage und die Funktion, die gerade lief, erhalten, sodass du sehen kannst, welches Plugin oder welcher Code die Zeit gekostet hat.

4️⃣ Apache anbinden: VirtualHost-Einstellungen und Socket-Rechte

Apache übergibt Anfragen an PHP-Dateien mit dem Modul mod_proxy_fcgi an den Socket des Pools. Du setzt eine SetHandler-Zeile in das FilesMatch im VirtualHost und trägst für jede Website den Socket ihres Kontos ein.

# Ein VirtualHost je Website-Konto · in SetHandler kommt der Socket dieses Kontos (statt SetHandler lässt sich auch mit ProxyPassMatch anbinden)
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /home/siteuser/www

    <Directory /home/siteuser/www>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php-fpm/siteuser.sock|fcgi://localhost"
    </FilesMatch>
</VirtualHost>

DocumentRoot und Directory sind das Web-Stammverzeichnis dieses Kontos, und -Indexes bei Options verhindert, dass die Ordnerliste im Browser sichtbar wird.

🔲 Socket-Rechte einstellen

Beim Start des Pools wird der Socket mit den Werten von listen.owner, listen.group und listen.mode erstellt, und mit ls prüfst du, ob die Rechte stimmen.

ls -l /run/php-fpm/
insgesamt 4
srw-rw----  1 siteuser_a nobody 0 Okt 22 23:34 siteuser_a.sock
-rw-r--r--  1 root       root   7 Okt 26 03:00 php-fpm.pid
srw-rw----  1 siteuser_b nobody 0 Okt 22 23:34 siteuser_b.sock
srw-rw----+ 1 root       root   0 Okt 22 23:34 www.sock

Stimmen die Rechte nicht und der Webserver kann den Socket nicht öffnen, bekommen Besucher einen 503-Fehler; um es ohne Neustart sofort zu beheben, legst du Besitzer und Rechte mit chown und chmod fest.

Das ist die aktuelle Syntax, bei der Benutzer und Gruppe durch einen Doppelpunkt getrennt werden.

chown siteuser:nobody /run/php-fpm/siteuser.sock

Setze nach dem Ändern des Besitzers die Rechte auf 660.

chmod 660 /run/php-fpm/siteuser.sock

Das ist die alte Syntax, bei der Benutzer und Gruppe durch einen Punkt getrennt werden, und sie läuft in chown auch unter AlmaLinux 9 unverändert.

chown siteuser.nobody /run/php-fpm/siteuser.sock

Setze nach dem Ändern des Besitzers die Rechte auf 660.

chmod 660 /run/php-fpm/siteuser.sock

Beide Syntaxen führen zum selben Ergebnis: Welche du auch verwendest, der Besitzer des Sockets wird siteuser und die Gruppe nobody.

🔲 Nginx anbinden: die Einstellung fastcgi_pass

In Nginx übergibt das location für PHP-Dateien im server-Block die Anfragen mit fastcgi_pass an den Socket desselben Pools.

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/run/php-fpm/siteuser.sock;
}

Läuft Nginx unter dem Konto nginx, musst du in der Pool-Datei bei listen.group nginx eintragen, damit es den Socket öffnen kann.

5️⃣ Konfiguration prüfen und neu starten: php-fpm -t und systemctl

Starte nach einer Änderung der Konfiguration nicht sofort neu, sondern führe zuerst mit php-fpm -t eine Syntaxprüfung durch. Steckt in einer Pool-Datei ein Tippfehler, fällt beim Neustart das gesamte PHP-FPM aus und alle Websites bekommen einen 503.

php-fpm -t
[26-Oct-2026 17:33:45] NOTICE: configuration file /etc/php-fpm.conf test is successful

Besteht die Prüfung, wird zusammen mit dem Pfad der Konfigurationsdatei die Meldung [test is successful] ausgegeben, und danach übernimmst du die Änderung in PHP-FPM. Änderungen, bei denen der Socket neu erstellt werden muss, etwa am Socket-Pfad oder an listen.owner, übernimmst du mit restart. Hast du auf einem laufenden Server nur Werte wie die Zahl der Worker geändert, übernimmst du sie mit reload.

systemctl restart php-fpm

Hast du den VirtualHost geändert, startest du auch Apache neu.

systemctl restart httpd

Trage es mit enable ein, damit es automatisch gestartet wird, wenn der Server wieder eingeschaltet wird.

systemctl enable php-fpm

Ob es eingetragen ist, prüfst du mit is-enabled.

systemctl is-enabled php-fpm
enabled

Mit status prüfst du, ob für jeden Pool Worker laufen.

systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
     Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; preset: disabled)
     Active: active (running) since x
    Process: 3934033 ExecReload=/bin/kill -USR2 $MAINPID (code=exited, status=0/SUCCESS)
   Main PID: 1333314 (php-fpm)
     Status: "Processes active: 4, idle: 21, Requests: x, slow: 0, Traffic: x"
      Tasks: x
     Memory: x
        CPU: x
     CGroup: /system.slice/php-fpm.service
             ├─  41920 "php-fpm: pool siteuser_a"
             ├─  94143 "php-fpm: pool siteuser_b"
             ├─1333314 "php-fpm: master process (/etc/php-fpm.conf)"
             ├─3934078 "php-fpm: pool www"
             └─4009016 "php-fpm: pool siteuser_a"

Okt 26 03:00:01 server.example.com systemd[1]: Reloading The PHP FastCGI Process Manager...
Okt 26 03:00:01 server.example.com systemd[1]: Reloaded The PHP FastCGI Process Manager.

In der Status-Zeile sind active und idle die Worker, die gerade Anfragen bearbeiten, und die freien Worker, und unter CGroup sind die Worker nach Pool-Namen aufgelistet. Der Hostname und die Pool-Namen in der Ausgabe wurden durch Beispielwerte ersetzt.

🔢 FAQ & empfohlene Inhalte

mod_php führt PHP innerhalb des Apache-Prozesses aus, die Einrichtung ist daher einfach, aber PHP wird in jedem Apache-Worker geladen, was viel Speicher braucht und es schwer macht, das Ausführungskonto je Website zu trennen. PHP-FPM trennt PHP in eigene Prozesse ab, sodass jede Website ihr eigenes Konto und ihre eigene Zahl an Workern bekommen kann; auf einem Server mit mehreren Websites oder mit Nginx verwendest du deshalb PHP-FPM.

systemctl reload php-fpm schickt ein USR2-Signal an den Master-Prozess, der die Einstellungen neu einliest und die Worker austauscht. Wenn du process_control_timeout setzt, werden zuerst die Worker ausgetauscht, die ihre laufende Anfrage beendet haben (laut offizieller Dokumentation). restart fährt alle Worker auf einmal herunter und wieder hoch, sodass Anfragen in diesem Moment abbrechen können; auf einem laufenden Server verwendest du deshalb zuerst reload.

Auf Systemen der RHEL-Familie ist das Standardlog [/var/log/php-fpm/error.log], und dort bleiben Warnungen über fehlende Worker (seems busy · max_children) sowie die Einträge zum Start und Stopp der Pools erhalten. In der Datei, die du je Pool mit php_admin_value[error_log] festlegst, werden die Fehler des PHP-Codes dieser Website getrennt aufgezeichnet. Der Standard-Pool schreibt nach [/var/log/php-fpm/www-error.log].

ℹ️ Affiliate-Hinweis
Die Inhalte dieser Website enthalten Affiliate-Links. Kauft ein Besucher über einen dieser Links ein Produkt oder eine Dienstleistung, erhält die Website vom Verkäufer eine Provision. Der Betrag, den der Käufer zahlt(bei Aktionsrabatten sinkt er ↓), steigt dadurch nicht. Angegebene Preise, Rabatte und Lagerbestände entsprechen dem Stand bei Erstellung und können abweichen; prüfe sie daher vor dem Kauf beim Verkäufer. Produkte werden nach eigenen Kriterien ausgewählt und bewertet, und Provisionen beeinflussen weder die Reihenfolge noch den Inhalt der Bewertungen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Beweisen Sie, dass Sie ein Mensch sind: 0   +   4   =