PHP‑FPM z Nginx – jak skonfigurować szybkie środowisko PHP

Oskar Gajzler
Przez
Oskar Gajzler
Redaktor IINTE.edu.pl, na co dzień zajmuje się technologiami internetowymi i tłumaczeniem skomplikowanych tematów na prosty język. Pisze poradniki o tym, jak załatwiać sprawy przez internet, jak...
12 min czytania

1. Co to jest PHP‑FPM i dlaczego z Nginx?

PHP‑FPM (PHP FastCGI Process Manager) to zaawansowany menedżer procesów PHP, który nasłuchuje na porcie TCP lub gnieździe UNIX (socket) i obsługuje żądania przychodzące najczęściej z Nginx.

W odróżnieniu od klasycznego mod_php w Apache, PHP działa jako osobna usługa – dzięki temu:

  • nginx może obsługiwać statyczne pliki (CSS, JS, obrazki) bardzo szybko,
  • php‑fpm zarządza procesami PHP, skalując je do obciążenia (pule, limity, restartowanie, logi),
  • można łatwo uruchomić wiele wersji PHP równolegle.

Połączenie Nginx + PHP‑FPM jest obecnie standardem w środowiskach o dużym ruchu.

2. Założenia poradnika

Poniżej przyjmujemy następujące założenia konfiguracyjne:

  • system: typowy Linux (Debian/Ubuntu, analogicznie w innych – Fedora/AlmaLinux/CentOS itp.),
  • php: dowolna nowoczesna wersja (np. 8.2/8.3),
  • serwer http: Nginx jako reverse proxy + serwer plików statycznych,
  • sposób komunikacji: UNIX socket (szybszy i bezpieczniejszy na jednym serwerze niż port TCP).

3. Instalacja Nginx i PHP‑FPM

3.1. Aktualizacja systemu

Zaktualizuj pakiety systemowe:

sudo apt-get update && sudo apt-get upgrade

3.2. Instalacja Nginx

Zainstaluj serwer Nginx:

sudo apt-get install nginx

Po instalacji włącz usługę w autostarcie i uruchom:

sudo systemctl enable nginx
sudo systemctl start nginx

Sprawdź status usługi:

sudo systemctl status nginx

3.3. Instalacja PHP z FPM

Na Debianie/Ubuntu (przykład dla PHP 8.2) zainstaluj FPM i typowe rozszerzenia:

sudo apt-get install php8.2-fpm php8.2-cli php8.2-mysql php8.2-xml php8.2-curl php8.2-zip

Upewnij się, że zainstalowany jest pakiet phpX.Y-fpm – bez tego FPM nie będzie działał.

Uruchom i włącz PHP‑FPM:

sudo systemctl enable php8.2-fpm
sudo systemctl start php8.2-fpm
sudo systemctl status php8.2-fpm

4. Struktura katalogów i wirtualny host Nginx

4.1. Katalog projektu

Załóżmy, że konfigurujesz domenę example.net. Utwórz katalog projektu i nadaj prawa:

sudo mkdir -p /var/www/example.net/html
sudo chown -R www-data:www-data /var/www/example.net
sudo chmod -R 750 /var/www/example.net

Utwórz prosty plik testowy, aby sprawdzić serwowanie statyki:

echo "Hello Nginx" | sudo tee /var/www/example.net/html/index.html

4.2. Plik vhosta (blok serwera) Nginx

Skopiuj domyślny vhost jako szablon nowej domeny:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.net

Edytuj konfigurację:

sudo nano /etc/nginx/sites-available/example.net

Poniżej znajdziesz przykładową konfigurację HTTP (bez HTTPS, do testów):

server {
listen 80;
server_name example.net www.example.net;

root /var/www/example.net/html;
index index.php index.html index.htm;

# Obsługa plików statycznych
location / {
try_files $uri $uri/ /index.php?$query_string;
}

# Blok PHP – integracja z PHP-FPM przez socket
location ~ \.php$ {
try_files $uri =404;
include snippets/fastcgi-php.conf; # zawiera standardowe parametry FastCGI
fastcgi_pass unix:/run/php/php8.2-fpm.sock; # dostosuj wersję PHP!
# Alternatywnie dla innych dystrybucji:
# fastcgi_pass unix:/var/run/php-fpm/www.sock;
}

# Blokowanie dostępu do ukrytych plików (.git itp.)
location ~ /\.ht {
deny all;
}

access_log /var/log/nginx/example.net.access.log;
error_log /var/log/nginx/example.net.error.log;
}

Włącz vhost dla domeny:

sudo ln -s /etc/nginx/sites-available/example.net /etc/nginx/sites-enabled/

Wyłącz domyślny vhost (opcjonalnie):

sudo rm /etc/nginx/sites-enabled/default

5. Powiązanie Nginx z PHP‑FPM – socket

Kluczowy fragment w bloku location ~ \.php$ to wskazanie gniazda FPM:

fastcgi_pass unix:/run/php/php8.2-fpm.sock;

Ścieżkę do socketa znajdziesz w konfiguracji puli FPM, np. w pliku /etc/php/8.2/fpm/pool.d/www.conf (Debian/Ubuntu) albo /etc/php-fpm.d/www.conf (CentOS/Fedora).

Wyszukaj linię zawierającą ścieżkę do gniazda:

listen = /run/php/php8.2-fpm.sock

Jeśli ścieżka jest inna, przepisz ją dokładnie do dyrektywy fastcgi_pass w Nginx.

6. Sprawdzenie konfiguracji i restart usług

Po edycji konfiguracji Nginx wykonaj test składni:

sudo nginx -t

Jeśli nie ma błędów, przeładuj Nginx bez przerywania pracy:

sudo systemctl reload nginx

Po zmianach w PHP / PHP‑FPM (np. php.ini, pule) zrestartuj FPM:

sudo systemctl restart php8.2-fpm

W bardziej zaawansowanych środowiskach można użyć systemctl reload lub sygnału USR2 do płynnego przeładowania, ale pełny restart jest wymagany przy zmianach rozszerzeń, php.ini czy plików binarnych PHP.

7. Test – czy PHP działa?

Utwórz plik info.php, aby potwierdzić działanie PHP:

echo "<?php phpinfo(); ?>" | sudo tee /var/www/example.net/html/info.php

Wejdź w przeglądarce na adres http://example.net/info.php.

Jeżeli widzisz stronę z konfiguracją PHP, komunikacja Nginx ↔ PHP‑FPM działa.

Jeśli zamiast tego plik się pobiera, Nginx nie przekazuje żądań do FPM. Najczęściej winne są:

  • brak bloku location ~ \.php$,
  • zła ścieżka w fastcgi_pass,
  • niedziałający PHP‑FPM (systemctl status php8.2-fpm).

8. Podstawowa optymalizacja PHP (php.ini)

Plik php.ini dla FPM znajdziesz m.in. w /etc/php/8.2/fpm/php.ini (Debian/Ubuntu) lub w /etc/php.ini//etc/php-fpm.d/* (inne dystrybucje).

Warto dopasować kilka podstawowych parametrów w celu poprawy stabilności i wydajności:

  • memory_limit = 256M – ograniczenie pamięci na proces PHP (zwiększ dla ciężkich aplikacji);
  • max_execution_time = 60–300 – maksymalny czas wykonywania w sekundach; 300 s to bezpieczny limit dla długich importów;
  • post_max_size = 32M–64M – maksymalny rozmiar danych POST (formularze, JSON);
  • upload_max_filesize = 32M–64M – maksymalny rozmiar pojedynczego pliku przy uploadzie;
  • date.timezone = Europe/Warsaw – poprawna strefa czasu.

Po zmianach zrestartuj FPM:

sudo systemctl restart php8.2-fpm

9. Optymalizacja PHP‑FPM – pule i limity

Najważniejsza część wydajności PHP‑FPM to konfiguracja puli (plik www.conf lub osobne pule per aplikacja). Na Debian/Ubuntu znajdziesz ją w /etc/php/8.2/fpm/pool.d/www.conf, a na RHEL/Fedora w /etc/php-fpm.d/www.conf.

9.1. Tryby zarządzania procesami – dynamic, static, ondemand

Poniżej przykładowe dyrektywy sterujące liczbą procesów i ich zachowaniem:

pm = dynamic ; lub static / ondemand
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 10

  • pm = dynamic – domyślne i dobre w większości przypadków; FPM sam dostosowuje liczbę procesów w zależności od obciążenia;
  • pm = static – stała liczba procesów (pm.max_children); dobra przy dokładnej kontroli RAM;
  • pm = ondemand – procesy są tworzone na żądanie i usypiane po czasie (pm.process_idle_timeout), korzystne na małe serwery o niskim ruchu.

Dobór wartości kluczowych parametrów zależy od dostępnej pamięci i profilu ruchu. pm.max_children wyznaczysz w przybliżeniu jako: RAM dostępny dla PHP / średnie zużycie pamięci przez pojedynczy proces. Parametry pm.start_servers, pm.min_spare_servers, pm.max_spare_servers ustaw zgodnie ze średnim ruchem (dla małych serwisów zwykle 2–5).

9.2. Timeouty i logowanie powolnych skryptów

Włącz limity czasu i slowlog, aby diagnozować wąskie gardła w aplikacji:

request_terminate_timeout = 120
request_slowlog_timeout = 5s
slowlog = /var/log/php8.2-fpm/slow.log

Dzięki tym ustawieniom skrypty wiszące dłużej niż 120 s będą ubijane, a skrypty wykonujące się dłużej niż 5 s trafią do loga powolnych zapytań (slow.log).

9.3. Izolacja aplikacji w osobnych pulach

Dla wielu aplikacji (np. kilku klientów lub dużych serwisów) warto stworzyć osobne pule FPM – każdą z innymi limitami oraz użytkownikiem/UID. Polega to na skopiowaniu www.conf do app1.conf, zmianie nazwy puli i gniazda (listen), a następnie skierowaniu odpowiedniego vhosta Nginx na nowe gniazdo.

Dzięki temu awaria lub nadmierne zużycie RAM przez jedną aplikację nie wpływa na pozostałe oraz możesz stosować różne limity (pm.max_children), logi i użytkowników.

10. Optymalizacja Nginx pod PHP‑FPM

10.1. Kluczowy blok dla PHP

Najlepszą praktyką jest użycie gotowego snippetu fastcgi-php.conf (Debian/Ubuntu) oraz ustawienie try_files:

location ~ \.php$ {
try_files $uri =404;
include snippets/fastcgi-php.conf; # zawiera m.in. SCRIPT_FILENAME
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}

Jeśli snippet nie jest dostępny, ustaw parametry ręcznie:

location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

10.2. Bufory FastCGI

W pliku globalnym (np. /etc/nginx/nginx.conf) lub w sekcji http { ... } dopasuj bufory i timeouty:

fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
fastcgi_busy_buffers_size 64k;
fastcgi_read_timeout 60s;

Odpowiednio dobrane bufory zmniejszają ryzyko duplikowania ruchu między pamięcią a dyskiem i poprawiają wydajność odpowiedzi dynamicznych.

10.3. Gzip, kompresja i cache statyki

Włącz kompresję i nagłówki cache dla plików statycznych:

gzip on;
gzip_types text/plain text/css application/json application/javascript application/xml text/xml;
gzip_min_length 1024;
gzip_comp_level 5;

location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|webp)$ {
expires 30d;
access_log off;
}

Nginx świetnie radzi sobie z cache’owaniem statyki, znacząco odciążając PHP‑FPM.

11. Typowe problemy i diagnostyka

11.1. Strona pobiera plik PHP zamiast go wykonać

Najczęstsze przyczyny to błędny blok obsługi PHP, nieprawidłowe gniazdo FPM lub niedziałająca usługa:

  • brak bloku location ~ \.php$,
  • nieprawidłowa ścieżka w fastcgi_pass,
  • niedziałający PHP‑FPM.

Przydatne komendy diagnostyczne:

sudo nginx -t
sudo systemctl status php8.2-fpm
sudo tail -f /var/log/nginx/error.log

11.2. Błędy 502 Bad Gateway

Błędy 502 zwykle wynikają z problemu po stronie FPM lub ścieżki do gniazda:

  • niedziałający FPM (systemctl status php8.2-fpm),
  • zła ścieżka do socketa,
  • przeciążony FPM (pm.max_children za małe – rośnie kolejka).

Sprawdź logi FPM oraz log Nginx dla danej domeny:

sudo tail -f /var/log/php8.2-fpm.log

11.3. Serwer wolny „pod obciążeniem”

Główne potencjalne źródła problemu to limity procesów, pamięć lub brak cache kodu:

  • za mało procesów FPM (pm.max_children),
  • zbyt mały RAM i/lub swap (procesy PHP ubijane przez OOM),
  • brak lub źle skonfigurowany opcache PHP.

Włącz slowlog (slowlog, request_slowlog_timeout) i przeanalizuj, które skrypty spowalniają aplikację.

12. Dobre praktyki bezpieczeństwa

Aby ograniczyć ryzyko incydentów, stosuj poniższe zasady:

  • używaj kont nieuprzywilejowanych – uruchamiaj Nginx jako www-data (Debian/Ubuntu) lub inny dedykowany użytkownik;
  • ograniczaj prawa do katalogów – np. /var/www z uprawnieniami 750 i właścicielem użytkownika serwującego stronę;
  • filtruj dostęp do plików wrażliwych – blokuj .git, .env, pliki konfiguracyjne itp.

Przykładowa reguła Nginx blokująca dostęp do ukrytych plików:

location ~ /\.(git|env).* {
deny all;
}

Włącz HTTPS (Let’s Encrypt, certbot): wygeneruj certyfikat i dodaj listen 443 ssl; oraz ścieżki do certyfikatów w bloku server.

13. Podsumowanie kroków (checklista do szybkiego wdrożenia)

  1. Zainstaluj Nginx i PHP‑FPM wraz z wymaganymi rozszerzeniami.
  2. Upewnij się, że działa usługa phpX.Y-fpm (systemctl status).
  3. Utwórz katalog /var/www/twoja_domena/html i nadaj odpowiednie prawa.
  4. Skonfiguruj vhost Nginx z następującymi elementami:
  • root ustawiony na katalog strony,
  • blok location / z try_files,
  • blok location ~ \.php$ z fastcgi_pass na socket FPM.
  1. Sprawdź konfigurację Nginx (nginx -t) i przeładuj serwer.
  2. Dodaj info.php i przetestuj w przeglądarce, czy PHP działa.
  3. Dostosuj php.ini (limity pamięci, upload, czas wykonania).
  4. Skonfiguruj pule FPM (www.conf): pm, pm.max_children, timeouty, slowlog.
  5. Włącz gzip, cache statycznych plików i odpowiednie bufory FastCGI w Nginx.
  6. Monitoruj logi Nginx i PHP‑FPM, reaguj na 502/504 oraz długie czasy odpowiedzi.
Udostępnij ten artykuł
Obserwuj
Redaktor IINTE.edu.pl, na co dzień zajmuje się technologiami internetowymi i tłumaczeniem skomplikowanych tematów na prosty język. Pisze poradniki o tym, jak załatwiać sprawy przez internet, jak bezpiecznie korzystać z sieci i jak dobierać sprzęt oraz oprogramowanie. Prywatnie tropi nowinki technologiczne i testuje je, zanim opisze.
Brak komentarzy

Dodaj komentarz

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