Was ist PHP-FPM | PHP-FPM installieren und einrichten
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.
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-fpmphp-fpm-8.3.36-1.module_php.8.3.el9.remi.x86_64Ist die Ausgabe leer, ist es nicht installiert; dann installierst du es mit dnf.
dnf -y install php-fpmWenn 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.conflisten = /run/php-fpm/www.sock
pm = dynamiclisten 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 = 100Der 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 = 18Der 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.
| Modus | Wie Worker gestartet werden | Passende Websites |
|---|---|---|
| static (statisch) | Hält immer die in pm.max_children eingetragene Anzahl am Laufen | Websites 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_servers | Websites, deren Zugriffe schwanken |
| ondemand | Startet nur, wenn eine Anfrage kommt, und endet, sobald pm.process_idle_timeout verstrichen ist | Websites 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 = 128MDie 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.confIn 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/wwwlisten.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 = 0660Diese 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 = 0In 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.sockStimmen 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.sockSetze nach dem Ändern des Besitzers die Rechte auf 660.
chmod 660 /run/php-fpm/siteuser.sockDas 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.sockSetze nach dem Ändern des Besitzers die Rechte auf 660.
chmod 660 /run/php-fpm/siteuser.sockBeide 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 successfulBesteht 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-fpmHast du den VirtualHost geändert, startest du auch Apache neu.
systemctl restart httpdTrage es mit enable ein, damit es automatisch gestartet wird, wenn der Server wieder eingeschaltet wird.
systemctl enable php-fpmOb es eingetragen ist, prüfst du mit is-enabled.
systemctl is-enabled php-fpmenabledMit 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
Cache
Was ist Cache? Definition und alle Bereiche, in denen Caching genutzt wird
Erklärt nach Bereichen, wie Anfragen, die den Cache treffen, gar nicht erst bis zu einem PHP-FPM-Worker kommen.
Cache-Server
Varnish Cache für Apache und Nginx installieren und einrichten
Die Installationsschritte, mit denen du einen Cache-Server vor den Webserver setzt, um die PHP-Anfragen selbst zu verringern.
Linux
15 Kategorien von Linux-Befehlen
Eine Tabelle, die Befehle in 15 Kategorien einordnet, darunter rpm, grep und systemctl, die in diesem Beitrag verwendet wurden.
ℹ️ 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.