PHP-FPM (FastCGI Process Manager) to warstwa, która łączy serwer WWW z WordPressem. Każda dynamiczna strona, żądanie AJAX, akcja w panelu administracyjnym i transakcja WooCommerce przechodzi przez PHP-FPM. Źle skonfigurowany PHP-FPM to najczęstsza przyczyna błędów 502/504 i spowolnień WordPress pod obciążeniem. W tym artykule wyjaśniamy, czym jest PHP-FPM, dlaczego zastąpił mod_php, jak prawidłowo skonfigurować pool-e i dyrektywy pm.*, jak diagnozować problemy oraz jak zabezpieczyć PHP-FPM w środowisku produkcyjnym.
Czym jest PHP-FPM i dlaczego zastąpił mod_php
PHP-FPM to osobny demon zarządzający pulą procesów PHP, komunikujący się z serwerem WWW (Nginx lub Apache) przez protokół FastCGI. To standard w nowoczesnym hostingu WordPress — zastąpił starszy mod_php, który ładował interpreter PHP bezpośrednio do procesu Apache.
FastCGI Process Manager
PHP-FPM to implementacja FastCGI dla PHP z zaawansowanym zarządzaniem procesami. Utrzymuje pulę gotowych procesów PHP (workerów), które czekają na żądania od serwera WWW. Gdy przychodzi żądanie — wolny worker je przetwarza i zwraca wynik. Gdy worker kończy — wraca do puli. Serwer WWW nie musi wiedzieć nic o PHP — po prostu przekazuje żądanie do socketu PHP-FPM.
PHP-FPM vs mod_php
mod_php ładuje interpreter PHP do każdego procesu Apache — nawet gdy ten serwuje plik CSS. Wynik: ogromne zużycie RAM, brak izolacji, wymuszenie MPM Prefork (najwolniejszego). PHP-FPM to osobny proces — Apache lub Nginx obsługuje połączenia HTTP, a PHP uruchamia się tylko gdy jest potrzebny. Mniej RAM, lepsza izolacja, kompatybilność z MPM Event i Nginx.
Osobne procesy, osobne pool-e
Każda strona WordPress może mieć własny pool PHP-FPM z osobnym użytkownikiem systemowym, limitem pamięci i liczbą workerów. Awaria jednej strony nie wpływa na inne. Włamanie do jednej strony nie daje dostępu do plików innej. To fundament bezpieczeństwa w środowiskach multi-tenant — wielu stron na jednym serwerze.
Działa z Nginx i Apache
PHP-FPM jest niezależny od serwera WWW. Nginx komunikuje się przez fastcgi_pass (unix socket lub TCP). Apache — przez mod_proxy_fcgi z SetHandler lub ProxyPassMatch. W konfiguracji reverse proxy PHP-FPM to backend, który obsługuje wyłącznie żądania PHP — resztę (pliki statyczne, SSL) obsługuje serwer WWW.
Konfiguracja pool-ów PHP-FPM pod WordPress
Pool to niezależna pula procesów PHP-FPM z własną konfiguracją. Każda strona WordPress powinna mieć osobny pool — dla izolacji zasobów, bezpieczeństwa i możliwości niezależnego tuningu. Pliki konfiguracyjne pool-ów znajdują się zwykle w /etc/php/8.x/fpm/pool.d/.
.conf per stronę WordPress (np. example-com.conf). Każdy pool działa pod osobnym użytkownikiem systemowym (user = example, group = example). Izolacja: użytkownik jednej strony nie może czytać ani modyfikować plików innej. Awaria PHP w jednym pool-u nie wpływa na pozostałe.pm = static — stała liczba workerów, najszybszy czas odpowiedzi, stałe zużycie RAM. Najlepszy dla serwerów dedykowanych z przewidywalnym ruchem. pm = dynamic — automatyczne skalowanie workerów, optymalny dla większości stron WordPress. pm = ondemand — workery tworzone tylko na żądanie, minimalne zużycie RAM, lekkie opóźnienie przy pierwszym żądaniu. Najlepszy dla wielu stron o niskim ruchu.ps -ylC php-fpm --sort:rss. Typowy proces WordPress: 40–80 MB. Dla WooCommerce: 60–120 MB. Przykład: 4 GB RAM, 2 GB dla PHP-FPM, proces ~60 MB → pm.max_children = 30. Zawsze zostawiaj 15–20% bufora.pm = dynamic. pm.start_servers — ile workerów uruchomić na starcie (~25% max_children). pm.min_spare_servers — minimum wolnych workerów (~10–15% max_children). pm.max_spare_servers — maximum wolnych workerów (~35% max_children). PHP-FPM automatycznie tworzy i zabija workery w tych granicach.listen = /run/php/php8.4-fpm-example.sock) jest szybszy niż TCP (listen = 127.0.0.1:9000) — eliminuje overhead stosu sieciowego. Używaj socket-ów gdy serwer WWW i PHP-FPM są na tym samym serwerze. TCP tylko gdy PHP-FPM działa na osobnej maszynie. Uprawnienia socketu muszą zgadzać się z użytkownikiem serwera WWW (www-data).pm.max_requests = 500 — po 500 żądaniach worker jest restartowany. Zapobiega wyciekowi pamięci z wtyczek WordPress, które nie zwalniają zasobów poprawnie. slowlog = /var/log/php-fpm/example-slow.log z request_slowlog_timeout = 5s — loguje stack trace żądań trwających dłużej niż 5 sekund. Najlepsza metoda znajdowania wolnych wtyczek i zapytań.Tuning PHP-FPM — jak dobrać parametry do serwera
Domyślne ustawienia PHP-FPM (pm.max_children = 5 na wielu dystrybucjach) są zaprojektowane pod bezpieczeństwo, nie wydajność. Na serwerze z 4 GB RAM domyślna konfiguracja wykorzystuje zaledwie 10–15% dostępnej mocy. Tuning wymaga pomiarów — nie zgadywania.
Obliczanie RAM per proces
Komenda ps -ylC php-fpm --sort:rss pokazuje RSS (Resident Set Size) każdego workera w KB. Typowy worker WordPress: 40–80 MB. WooCommerce z rozbudowanymi wtyczkami: 60–120 MB. Ciężkie wtyczki (page buildery, membership) mogą podnosić zużycie do 150+ MB. Mierz pod realnym obciążeniem, nie na pustym serwerze.
pm.max_children a OOM killer
Zbyt wysoki pm.max_children → serwer wchodzi w swap → dramatyczne spowolnienie → OOM killer zabija procesy (często MySQL, nie PHP-FPM). Zbyt niski → żądania czekają w kolejce → błędy 502/504. Formuła: (RAM serwera − RAM system − RAM MySQL − RAM serwer WWW) / RAM per worker × 0.85 (bufor). Monitoruj po wdrożeniu i koryguj.
pm.status_path — monitoring w czasie rzeczywistym
Dyrektywa pm.status_path = /php-fpm-status w pool-u + blok location w Nginx (ograniczony do localhost). Pokazuje: aktywne procesy, idle procesy, max children reached (ile razy osiągnięto limit), listen queue (ile żądań czeka). Jeśli max children reached > 0 — trzeba zwiększyć pm.max_children lub zoptymalizować PHP.
OPcache — wpływ na PHP-FPM
OPcache przechowuje skompilowany bytecode PHP w pamięci współdzielonej — workery nie muszą parsować plików PHP przy każdym żądaniu. Skraca czas wykonania o 50–70%. Szybszy worker = szybciej zwalnia slot = więcej żądań przy tej samej liczbie workerów. opcache.memory_consumption = 128 i opcache.max_accelerated_files = 10000 to dobry punkt startowy dla WordPress. Więcej o wersji PHP w artykule WordPress a wydajność PHP.
JIT w PHP 8.x — kiedy pomaga
JIT (Just-In-Time compilation) w PHP 8.0+ kompiluje bytecode do kodu maszynowego w runtime. Dla typowego WordPressa (operacje I/O: baza danych, HTTP) zysk jest minimalny — JIT pomaga przy operacjach CPU-intensive. Dla WooCommerce z ciężkimi kalkulacjami (rabaty, podatki, shipping) i stronach z dużą ilością logiki PHP — JIT może skrócić czas wykonania o 5–15%.
Redis/Memcached — odciążenie PHP-FPM
WordPress wykonuje dziesiątki zapytań SQL per żądanie. Object cache (Redis lub Memcached) przechowuje wyniki zapytań w pamięci — worker PHP-FPM pobiera dane z cache zamiast odpytywać bazę. Krótszy czas wykonania żądania = worker szybciej wraca do puli = mniej potrzebnych workerów. Redis z wtyczką Redis Object Cache to standard na profesjonalnych hostingach WordPress.
PHP-FPM z Nginx vs PHP-FPM z Apache
PHP-FPM jest niezależny od serwera WWW, ale integracja z Nginx i Apache różni się konfiguracją i subtelnymi różnicami wydajnościowymi.
fastcgi_pass unix:/run/php/php8.4-fpm.sock; w bloku location ~ \.php$. Nginx obsługuje pliki statyczne bezpośrednio, a do PHP-FPM przekazuje tylko żądania PHP. Natywne wsparcie FastCGI cache (fastcgi_cache) pozwala serwować odpowiedzi PHP z cache Nginx bez angażowania PHP-FPM.SetHandler "proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost" lub ProxyPassMatch. Wymaga włączenia mod_proxy i mod_proxy_fcgi. Pozwala na MPM Event zamiast Prefork (mod_php wymusza Prefork). Apache z PHP-FPM i MPM Event osiąga porównywalną wydajność z Nginx dla typowego ruchu WordPress.listen.owner = www-data musi zgadzać się z użytkownikiem Nginx/Apache.php8.3-fpm.sock po upgrade do PHP 8.4) → 502. Zawsze weryfikuj ścieżkę socketu po każdej aktualizacji PHP.Diagnostyka problemów PHP-FPM
Błędy 502 i 504 to najczęstsze objawy problemów z PHP-FPM. Diagnostyka wymaga sprawdzenia logów, statusu pool-u i zużycia zasobów. Poniżej najczęstsze problemy i ich rozwiązania.
systemctl status php8.4-fpm), błędna ścieżka socketu w konfiguracji serwera WWW, brak uprawnień do socketu, lub PHP-FPM crashnął (sprawdź /var/log/php8.4-fpm.log). Najszybsza diagnostyka: ls -la /run/php/ — sprawdź czy socket istnieje i ma właściwe uprawnienia.max_execution_time w php.ini, lub request_terminate_timeout w pool-u PHP-FPM. Rozwiązanie: sprawdź slowlog PHP-FPM, slow query log MySQL i dostosuj timeout-y. Nie podnoś timeout-ów bezkrytycznie — to maskuje prawdziwy problem.pm.max_children (jeśli masz zapas RAM), zoptymalizuj PHP (OPcache, object cache, szybsza baza danych) lub zmniejsz czas wykonania żądania. Sprawdź pm.status_path — ile razy limit został osiągnięty i jaka jest długość kolejki.pm.max_requests = 500 restartuje workera po 500 żądaniach — zwalnia skumulowaną pamięć. Jeśli pojedynczy worker zużywa ponad 150 MB — szukaj ciężkiej wtyczki (page builder, membership, backup). Komenda ps -o pid,rss,command -C php-fpm --sort=-rss pokazuje workerów posortowanych po zużyciu RAM.slowlog w konfiguracji pool-u loguje stack trace żądań przekraczających request_slowlog_timeout. Pokazuje dokładnie, jaka funkcja PHP w jakiej wtyczce jest odpowiedzialna za spowolnienie. To najskuteczniejsze narzędzie diagnostyczne PHP-FPM — wskazuje wprost na winowajcę, zamiast zmuszać do zgadywania.Bezpieczeństwo PHP-FPM
PHP-FPM to punkt, w którym kod PHP — w tym kod wtyczek i motywów WordPress — jest faktycznie wykonywany. Prawidłowa konfiguracja bezpieczeństwa PHP-FPM minimalizuje skutki ewentualnego włamania na jedną ze stron na serwerze.
user = site1, group = site1). Pliki WordPress należą do tego użytkownika. Wynik: PHP jednej strony nie może czytać ani modyfikować plików innej strony na tym samym serwerze. To najbardziej fundamentalne zabezpieczenie w środowiskach multi-site.php_admin_value[open_basedir] = /var/www/site1:/tmp w pool-u ogranicza dostęp PHP do wskazanych katalogów. Nawet jeśli atakujący uzyska zdalne wykonanie kodu — nie może czytać plików spoza katalogu strony. Nie może odczytać /etc/passwd, plików innych stron ani konfiguracji serwera.php_admin_value[disable_functions] = exec,passthru,shell_exec,system,proc_open,popen — wyłącza funkcje PHP pozwalające na wykonywanie komend systemowych. WordPress nie potrzebuje ich do normalnego działania. Blokuje typowy payload atakujących — nawet po wgraniu webshella, nie mogą uruchomić komend na serwerze. Uwaga: niektóre wtyczki backupowe mogą wymagać exec.chroot = /var/www/site1 izoluje cały proces PHP-FPM w katalogu strony — PHP nie widzi reszty systemu plików. Najsilniejsza izolacja, ale wymaga dostępności bibliotek, plików konfiguracyjnych i ścieżek socket-ów wewnątrz chroot. Bardziej złożona w konfiguracji niż open_basedir, ale oferuje izolację na poziomie systemu operacyjnego.Podsumowanie
PHP-FPM to fundament wydajności WordPress — warstwa, która bezpośrednio odpowiada za czas generowania każdej dynamicznej strony. Domyślne ustawienia PHP-FPM są zaprojektowane pod bezpieczeństwo, nie wydajność — tuning pm.max_children, wybór trybu pm (dynamic/static/ondemand) i konfiguracja OPcache mogą kilkukrotnie zwiększyć liczbę obsługiwanych żądań. Osobne pool-e per strona, open_basedir i disable_functions zapewniają izolację i bezpieczeństwo. Diagnostyka przez pm.status_path i slowlog pozwala znajdować problemy zanim wpłyną na użytkowników.
W WebOptimo konfigurujemy i tunujemy PHP-FPM pod WordPress i WooCommerce w ramach administracji serwerami i hostingu WordPress. Dobieramy parametry pool-ów do zasobów serwera, wdrażamy OPcache i Redis, diagnozujemy problemy wydajnościowe przez slowlog i monitoring. Jeśli Twoja strona spowalnia pod ruchem lub widzisz błędy 502/504 — skontaktuj się z nami lub sprawdź ofertę opieki WordPress.
Najczęstsze pytania o PHP-FPM i WordPress
mod_php ładuje interpreter PHP bezpośrednio do procesu Apache — każdy proces Apache zawiera pełny interpreter PHP, nawet obsługując pliki statyczne. PHP-FPM to osobny demon zarządzający pulą procesów PHP, komunikujący się z serwerem WWW przez protokół FastCGI. PHP-FPM pozwala na izolację procesów, osobne pool-e per strona, lepsze zarządzanie pamięcią i kompatybilność z Nginx oraz Apache MPM Event.
Zmierz średnie zużycie RAM jednego procesu PHP-FPM poleceniem ps. Odejmij od całkowitego RAM serwera pamięć potrzebną dla systemu, bazy danych i serwera WWW. Podziel dostępny RAM przez średni rozmiar procesu PHP. Zostaw 15–20% bufora bezpieczeństwa. Przykład: 4 GB RAM, 1.5 GB na system/MySQL/Nginx, proces ~60 MB → pm.max_children ≈ 35.
Błąd 502 oznacza, że serwer WWW (Nginx lub Apache) nie może połączyć się z PHP-FPM. Najczęstsze przyczyny: PHP-FPM nie działa, błędna ścieżka do socketu, uprawnienia socketu uniemożliwiające połączenie, lub wszystkie workery PHP-FPM są zajęte i nowe żądania nie mogą być obsłużone. Sprawdź status PHP-FPM i czy socket istnieje.
Dynamic to optymalny wybór dla większości stron WordPress — automatycznie skaluje liczbę workerów w zależności od ruchu. Static jest najlepszy dla serwerów dedykowanych z przewidywalnym, stałym ruchem. Ondemand sprawdza się na serwerach z wieloma stronami o niskim ruchu — workery są tworzone tylko gdy potrzebne i zwalniane po okresie bezczynności.
Tak. Nginx komunikuje się z PHP-FPM przez dyrektywę fastcgi_pass. Apache — przez mod_proxy_fcgi z dyrektywą SetHandler lub ProxyPassMatch. PHP-FPM jest niezależny od serwera WWW — to osobny proces, który może obsługiwać żądania z dowolnego serwera wspierającego protokół FastCGI.