Czym jest PHP-FPM | Instalacja i konfiguracja PHP-FPM

Środowisko testowe Rodzina RHELAlmaLinux 9.8Apache 2.4 + PHP-FPM 8.3konto rootSprawdzono 2026-10-26

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.

🧩 Jak CGI i PHP-FPM obsługują żądania
Diagram objaśniający
⚙️ Wykonywanie PHP
🌐 Serwer WWW
🌐 ApacheNginx
📨 Żądanie 1 · index.php📨 Żądanie 2 · wp-login.php📨 Żądanie 3 · index.php
Pliki statyczne (obrazy, CSS) serwer WWW obsługuje sam
Uruchamiane przy każdym żądaniuFastCGI · gniazdo→
🧱 Procesy CGI
Żądanie 1Nowy proces → obsługa → zakończenie
Żądanie 2Nowy proces → obsługa → zakończenie
Żądanie 3Nowy proces → obsługa → zakończenie
Gdy obsługa się kończy, proces też znika · następne żądanie zaczyna od nowa
🧰 Pula PHP-FPM [siteuser]
Worker 1Żądanie 1
Worker 2Żądanie 2
Worker 3Żądanie 3
Worker 4czekanie
Worker 5czekanie
Wcześniej uruchomione workery odbierają żądania, a po zakończeniu czekają na następne
Gdy Apache uruchamia PHP jako CGI, przy każdym żądaniu startuje nowy proces PHP i kończy go po obsłudze, więc im więcej żądań, tym bardziej kumuluje się koszt tworzenia procesów.
Nginx nie ma modułu, który uruchamiałby programy CGI bezpośrednio, więc tej kombinacji się nie używa; PHP jest przekazywane do PHP-FPM przez FastCGI.
Apache przekazuje żądania PHP do gniazda przez mod_proxy_fcgi, a wcześniej uruchomiony worker PHP-FPM je odbiera, obsługuje i czeka na następne.
Nginx przekazuje żądania do tego samego gniazda przez fastcgi_pass, więc nawet przy innym serwerze WWW pula PHP-FPM pozostaje ta sama.

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-fpm
php-fpm-8.3.36-1.module_php.8.3.el9.remi.x86_64

Jeśli wynik jest pusty, pakiet nie jest zainstalowany; zainstaluj go przez dnf.

dnf -y install php-fpm

Gdy 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.conf
listen = /run/php-fpm/www.sock
pm = dynamic

listen 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 = 100

Tryb 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 = 18

Tryb 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.

TrybSposób uruchamiania workerówOdpowiednie witryny
static (statyczny)Zawsze utrzymuje uruchomioną liczbę wpisaną w pm.max_childrenWitryny 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
ondemandUruchamia tylko po nadejściu żądania i kończy po upływie pm.process_idle_timeoutWitryny 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 = 128M

Te 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.conf

W 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/www

listen.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 = 0660

Te 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 = 0

W 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.sock

Jeś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.sock

Po zmianie właściciela ustaw uprawnienia na 660.

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

To 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.sock

Po zmianie właściciela ustaw uprawnienia na 660.

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

Wynik 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 successful

Jeś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-fpm

Jeśli edytujesz VirtualHost, zrestartuj też Apache.

systemctl restart httpd

Zarejestruj go przez enable, aby uruchamiał się automatycznie po ponownym włączeniu serwera.

systemctl enable php-fpm

To, czy jest zarejestrowany, sprawdzisz przez is-enabled.

systemctl is-enabled php-fpm
enabled

Przez 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

mod_php wykonuje PHP wewnątrz procesu Apache, więc konfiguracja jest prosta, ale PHP ładuje się w każdym workerze Apache, co zużywa dużo pamięci i utrudnia rozdzielenie konta wykonawczego dla poszczególnych witryn. PHP-FPM wydziela PHP do osobnych procesów, więc każda witryna może mieć własne konto i własną liczbę workerów; dlatego na serwerze z wieloma witrynami lub z Nginx używa się PHP-FPM.

systemctl reload php-fpm wysyła sygnał USR2 do procesu głównego, który ponownie wczytuje ustawienia i wymienia workery. Jeśli ustawisz process_control_timeout, wymieniane są najpierw workery, które skończyły obsługiwane żądanie (według oficjalnej dokumentacji). restart zatrzymuje wszystkie workery naraz i uruchamia je ponownie, więc żądania z tej chwili mogą zostać przerwane; na działającym serwerze używaj więc najpierw reload.

W rodzinie RHEL domyślny log to [/var/log/php-fpm/error.log] i tam zostają ostrzeżenia o braku workerów (seems busy · max_children) oraz zapisy uruchamiania i zatrzymywania pul. W pliku, który dla puli wskażesz przez php_admin_value[error_log], zapisują się osobno błędy kodu PHP tej witryny. Domyślna pula zapisuje do [/var/log/php-fpm/www-error.log].

ℹ️ 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.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *

Prove your humanity: 5   +   8   =