Czym jest PHP-FPM | Instalacja i konfiguracja PHP-FPM
PHP-FPM to menedżer procesów FastCGI, w którym wcześniej uruchomione procesy worker odbierają żądania PHP przekazane przez serwer WWW i je obsługują. Na serwerze AlmaLinux 9 z Apache ten przewodnik sprawdza, czy jest zainstalowany i jak ustawione są pule oraz gniazda poszczególnych witryn, a potem dochodzi do testu konfiguracji i sprawdzenia stanu na prawdziwych wynikach.
Apache potrafi też wykonywać PHP bezpośrednio przez mod_php, ale jeśli przekażesz je do PHP-FPM, serwer WWW i PHP są oddzielone. Nginx nie umie wykonywać PHP bezpośrednio, więc przekazuje żądania do procesu FastCGI, takiego jak PHP-FPM. Dlatego jeden PHP-FPM można podłączyć zarówno do Apache, jak i do Nginx. Ustawienia puli i budowa gniazd poniżej obowiązują bez zmian także wtedy, gdy łączysz PHP-FPM z Nginx.
1️⃣ Czym jest PHP-FPM: różnica między CGI a FastCGI
CGI (Common Gateway Interface) to standardowy sposób, w jaki serwer WWW uruchamia zewnętrzny program, by wygenerować treść dynamiczną, i przy każdym nadchodzącym żądaniu uruchamia program od nowa. Koszt tworzenia i usuwania procesu przy każdym żądaniu się kumuluje, więc im większy ruch, tym wolniej odpowiada serwer.
FastCGI usuwa ten koszt, uruchamiając program wcześniej i obsługując żądania jedno po drugim. To różnica między włączaniem i wyłączaniem komputera przy każdym użyciu a korzystaniem od razu z komputera, który już działa. PHP-FPM (FastCGI Process Manager) to menedżer, który uruchamia PHP przez FastCGI, i jest dołączony do PHP od wersji 5.3.3.
Dla każdej puli, czyli grupy workerów, PHP-FPM uruchamia wcześniej ustaloną liczbę workerów; wolny worker odbiera żądanie przekazane przez serwer WWW gniazdem, obsługuje je i czeka na następne. Pliki statyczne, takie jak obrazy i CSS, serwer WWW obsługuje sam, a do PHP-FPM trafiają tylko pliki PHP. Różni się wyłącznie sposób przekazywania żądań do gniazda: Apache używa modułu mod_proxy_fcgi, a Nginx ustawienia fastcgi_pass.
2️⃣ Instalacja PHP-FPM: sprawdzenie pakietu i instalacja przez dnf
Jeśli PHP zainstalowano przez dnf na serwerze z rodziny RHEL, pakiet php-fpm jest zainstalowany razem z nim. Najpierw sprawdź przez rpm, czy jest zainstalowany. Instalacja PHP przebiega tak samo jak w artykule Instalacja APM na Rocky Linux.
rpm -qa | grep php-fpmphp-fpm-8.3.36-1.module_php.8.3.el9.remi.x86_64Jeśli wynik jest pusty, pakiet nie jest zainstalowany; zainstaluj go przez dnf.
dnf -y install php-fpmGdy instalacja się skończy, uruchom to samo polecenie rpm jeszcze raz i sprawdź, czy wyświetla się nazwa pakietu.
3️⃣ Konfiguracja PHP-FPM: pula www.conf, gniazdo oraz tryb statyczny i dynamiczny
Pliki konfiguracji są dwa: ustawienia ogólne [/etc/php-fpm.conf] i ustawienia puli [/etc/php-fpm.d/www.conf]. W domyślnej puli www.conf najpierw patrz na linie listen i pm, a wartości tuż po instalacji są takie.
grep -E '^(listen|pm) ' /etc/php-fpm.d/www.conflisten = /run/php-fpm/www.sock
pm = dynamiclisten to miejsce, do którego serwer WWW przekazuje żądania, a domyślną wartością w wersji 8.3 jest gniazdo uniksowe [/run/php-fpm/www.sock]. Domyślna wartość starszych wersji, [127.0.0.1:9000], odbiera żądania przez port TCP. W obrębie jednego serwera gniazdo jest lżejsze, bo pomija proces łączenia przez port, a dzięki listen.owner i listen.group możesz ograniczyć dostęp tak jak uprawnieniami plików.
🔲 Ustawienia trybu statycznego i dynamicznego
pm to sposób uruchamiania workerów, a ustawiasz go na jedną z wartości: static, dynamic lub ondemand. Tryb statyczny zawsze utrzymuje uruchomioną liczbę wpisaną w pm.max_children, a poniższe ustawienie utrzymuje 100 workerów.
pm = static
pm.max_children = 100Tryb dynamiczny jest domyślny i zwiększa lub zmniejsza liczbę workerów zależnie od liczby żądań. Poniższe ustawienie uruchamia na starcie 12, utrzymuje od 6 do 18 wolnych workerów i rośnie maksymalnie do 120.
pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18Tryb ondemand uruchamia workery tylko wtedy, gdy nadejdzie żądanie, i kończy je po upływie pm.process_idle_timeout, więc pasuje do witryn z małym ruchem, a nie pasuje do witryn z dużym ruchem.
Te trzy tryby różnią się tym, kiedy uruchamiają workery i jak zmienia się ich liczba.
| Tryb | Sposób uruchamiania workerów | Odpowiednie witryny |
|---|---|---|
| static (statyczny) | Zawsze utrzymuje uruchomioną liczbę wpisaną w pm.max_children | Witryny z dużym ruchem |
| dynamic (dynamiczny) | Domyślny · zwiększa lub zmniejsza liczbę w granicach pm.start_servers, pm.min_spare_servers i pm.max_spare_servers zależnie od liczby żądań | Witryny, których ruch rośnie i maleje |
| ondemand | Uruchamia tylko po nadejściu żądania i kończy po upływie pm.process_idle_timeout | Witryny z małym ruchem |
max_children ustala się, dzieląc pamięć serwera przez pamięć zajmowaną przez jednego workera. Nawet gdy kumulują się ostrzeżenia o [max_children], nie zwiększaj go od razu, tylko najpierw ustal z logów, jakie żądania zapełniły workery.
Pamięć i limit przesyłania ustawia się w php.ini, czyli w ogólnych ustawieniach PHP, i dobiera razem z liczbą workerów do witryny, którą prowadzisz.
memory_limit = 1024M
post_max_size = 128M
upload_max_filesize = 128MTe trzy wartości to limit pamięci dla jednego skryptu PHP i rozmiar plików, które można przesłać naraz, a zaczynają obowiązywać dopiero po restarcie PHP-FPM.
🔲 Ustawienia puli dla każdego konta witryny
Przy wielu witrynach nie używasz jednego wspólnego www.conf, tylko tworzysz plik puli dla każdego konta i rozdzielasz konto wykonawcze oraz gniazdo. PHP jednej witryny nie może czytać plików innego konta, a liczbę workerów ustala się osobno dla każdej witryny.
vi /etc/php-fpm.d/siteuser.confW pliku wpisuje się nazwę puli, konto wykonawcze, ścieżkę gniazda i liczbę workerów.
[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 i listen.group to właściciel i grupa pliku gniazda, a PHP-FPM tworzy gniazdo z tymi wartościami przy starcie. Jeśli serwer WWW działa na koncie nobody, wpisz w listen.group nobody, a jeśli na koncie apache, wpisz apache, aby serwer WWW mógł otworzyć gniazdo.
listen.owner = siteuser
listen.group = nobody
listen.mode = 0660Te trzy linie trafiają do każdego pliku puli, a po zmianie wartości trzeba zrobić restart, żeby gniazdo zostało utworzone na nowo z nowymi uprawnieniami.
🔲 Ustawienia slowlog
slowlog to plik, w którym zapisuje się miejsce wykonania żądań trwających dłużej niż request_slowlog_timeout, a przy wartości 0 nic się nie zapisuje. Gdy szukasz przyczyny wolnych żądań, włącz go, podając czas w sekundach, na przykład 3s.
slowlog = /var/log/php-fpm/www-slow.log
request_slowlog_timeout = 0W zapisanym pliku zostaje ścieżka skryptu wolnego żądania i funkcja, która wtedy się wykonywała, więc możesz sprawdzić, jaka wtyczka lub jaki kod pochłonął czas.
4️⃣ Integracja z Apache: ustawienia VirtualHost i uprawnienia gniazda
Apache przekazuje żądania plików PHP do gniazda puli modułem mod_proxy_fcgi. W FilesMatch wewnątrz VirtualHost umieszczasz jedną linię SetHandler i dla każdej witryny wpisujesz gniazdo jej konta.
# Jeden VirtualHost na konto witryny · w SetHandler wpisz gniazdo tego konta (zamiast SetHandler można też połączyć przez ProxyPassMatch)
<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 i Directory to katalog główny WWW tego konta, a -Indexes w Options zapobiega wyświetlaniu listy folderów w przeglądarce.
🔲 Ustawianie uprawnień gniazda
Gdy pula startuje, gniazdo jest tworzone z wartościami listen.owner, listen.group i listen.mode, a przez ls sprawdzasz, czy uprawnienia są poprawne.
ls -l /run/php-fpm/razem 4
srw-rw---- 1 siteuser_a nobody 0 paź 22 23:34 siteuser_a.sock
-rw-r--r-- 1 root root 7 paź 26 03:00 php-fpm.pid
srw-rw---- 1 siteuser_b nobody 0 paź 22 23:34 siteuser_b.sock
srw-rw----+ 1 root root 0 paź 22 23:34 www.sockJeśli uprawnienia się nie zgadzają i serwer WWW nie może otworzyć gniazda, odwiedzający dostają błąd 503; aby to naprawić od razu bez restartu, ustaw właściciela i uprawnienia przez chown i chmod.
To obecna składnia, w której użytkownika i grupę oddziela dwukropek.
chown siteuser:nobody /run/php-fpm/siteuser.sockPo zmianie właściciela ustaw uprawnienia na 660.
chmod 660 /run/php-fpm/siteuser.sockTo stara składnia, w której użytkownika i grupę oddziela kropka, i chown na AlmaLinux 9 nadal ją wykonuje bez zmian.
chown siteuser.nobody /run/php-fpm/siteuser.sockPo zmianie właściciela ustaw uprawnienia na 660.
chmod 660 /run/php-fpm/siteuser.sockWynik obu składni jest taki sam: niezależnie od wybranej, właścicielem gniazda zostaje siteuser, a grupą nobody.
🔲 Integracja z Nginx: ustawienie fastcgi_pass
W Nginx location dla plików PHP wewnątrz bloku server przekazuje żądania do gniazda tej samej puli przez fastcgi_pass.
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php-fpm/siteuser.sock;
}Jeśli Nginx działa na koncie nginx, w pliku puli trzeba wpisać nginx w listen.group, aby mógł otworzyć gniazdo.
5️⃣ Test konfiguracji i restart: php-fpm -t i systemctl
Po zmianie konfiguracji nie rób od razu restartu, tylko najpierw sprawdź składnię przez php-fpm -t. Jeśli w pliku puli jest literówka, przy restarcie przestaje działać cały PHP-FPM i wszystkie witryny dostają błąd 503.
php-fpm -t[26-Oct-2026 17:33:45] NOTICE: configuration file /etc/php-fpm.conf test is successfulJeśli test się powiedzie, wyświetla się komunikat [test is successful] razem ze ścieżką pliku konfiguracji, a potem zmianę stosujesz w PHP-FPM. Zmiany wymagające ponownego utworzenia gniazda, takie jak ścieżka gniazda czy listen.owner, stosuje się przez restart. Jeśli na działającym serwerze zmieniasz tylko wartości takie jak liczba workerów, zastosuj je przez reload.
systemctl restart php-fpmJeśli edytujesz VirtualHost, zrestartuj też Apache.
systemctl restart httpdZarejestruj go przez enable, aby uruchamiał się automatycznie po ponownym włączeniu serwera.
systemctl enable php-fpmTo, czy jest zarejestrowany, sprawdzisz przez is-enabled.
systemctl is-enabled php-fpmenabledPrzez status sprawdzisz, czy dla każdej puli działają workery.
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"
paź 26 03:00:01 server.example.com systemd[1]: Reloading The PHP FastCGI Process Manager...
paź 26 03:00:01 server.example.com systemd[1]: Reloaded The PHP FastCGI Process Manager.W linii Status active i idle to workery obsługujące teraz żądania oraz wolne workery, a CGroup wymienia workery według nazwy puli. Nazwę hosta i nazwy pul w wyniku zastąpiono przykładowymi wartościami.
🔢 FAQ & polecane treści
Cache
Cache: definicja i wszystkie obszary, w których stosuje się buforowanie
Wyjaśnia dziedzina po dziedzinie, jak żądania trafiające w pamięć podręczną nigdy nie docierają do workera PHP-FPM.
Serwer pamięci podręcznej
Instalacja i konfiguracja Varnish Cache w Apache i Nginx
Kroki instalacji, w których serwer pamięci podręcznej stawia się przed serwerem WWW, aby zmniejszyć samą liczbę żądań PHP.
Linux
15 kategorii poleceń Linux
Tabela, która dzieli polecenia na 15 kategorii, w tym użyte w tym artykule rpm, grep i systemctl.
ℹ️ Informacja o linkach partnerskich
Treści tej witryny zawierają linki partnerskie. Jeśli odwiedzający kupi produkt lub usługę przez taki link, witryna otrzymuje od sprzedawcy prowizję. Kwota płacona przy tym przez kupującego (podczas promocji spada↓) nie wzrasta. Podane ceny, rabaty i dostępność odnoszą się do chwili pisania i mogą różnić się od stanu faktycznego, dlatego przed zakupem sprawdź je u sprzedawcy. Produkty wybieramy i oceniamy według własnych kryteriów, a prowizja nie wpływa ani na kolejność prezentacji, ani na treść ocen.