Заощадьте 15% на всіх хостингових послугах

Перевірте свої навички і отримайте Знижку на будь-який план хостингу

Використовуй код: Skills Почати
Рубрики
Адміністрація Віртуальні сервери

PHP-FPM (FastCGI Process Manager): Повний посібник з налаштування, конфігурації та оптимізації

PHP-FPM (PHP FastCGI Process Manager) — це високопродуктивний альтернативний менеджер процесів PHP, який реалізує протокол FastCGI для відокремлення виконання PHP від процесу веб-сервера. Замість того щоб запускати новий інтерпретатор PHP для кожного вхідного HTTP-запиту — як це робить традиційний CGI — PHP-FPM підтримує постійний пул робочих процесів, які приймають, виконують і повертають PHP-відповіді зі значно меншими накладними витратами.

Для будь-якого виробничого веб-сервера, що працює з WordPress, Laravel, Symfony або власними PHP-застосунками, PHP-FPM є стандартним обробником. Він забезпечує детальний контроль над життєвим циклом процесів, обмеженнями пам’яті, чергуванням запитів та ізоляцією для кожного застосунку — можливості, які просто недоступні з mod_php або звичайним CGI.

Чим PHP-FPM відрізняється від CGI та mod_php

Щоб зрозуміти, чому PHP-FPM важливий, корисно побачити, що саме він замінює і чому ці альтернативи не справляються з навантаженням.

ФункціяCGImod_phpPHP-FPM
Модель процесівНовий процес на кожен запитВбудований в ApacheПостійний пул воркерів
Ефективність пам’ятіДуже низькаПомірнаВідмінна
Зв’язок з веб-серверомТіснийТісний (лише Apache)Відокремлений (будь-який сервер)
Ізоляція для кожного сайтуВідсутняВідсутняПовна (окремі пули)
Плавне перезавантаженняНіНіТак
Slow log / профілюванняНіНіТак
Динамічне масштабування процесівНіНіТак
Підтримка Unix-сокетівНіНіТак
Сумісність з NGINXНіНіТак

CGI створює новий процес ОС для кожного запиту. При помірному трафіку це призводить до тисяч циклів fork/exec/exit на хвилину, перевантажуючи CPU та пам’ять. mod_php вбудовує інтерпретатор PHP безпосередньо в кожен воркер Apache, тобто кожен процес Apache — навіть той, що обслуговує статичне зображення — несе в пам’яті повне середовище виконання PHP. PHP-FPM вирішує обидві проблеми: воркери є постійними та повністю відокремленими від веб-сервера, тому NGINX або Apache обробляють статичні ресурси нативно, тоді як PHP-FPM обробляє лише виконання PHP.

Архітектура PHP-FPM: детальний потік запитів

Розуміння внутрішнього шляху запиту є необхідним для налаштування та налагодження.

  1. Браузер надсилає HTTP-запит на ресурс .php.
  2. Веб-сервер (NGINX або Apache) отримує запит і зіставляє його з блоком location або директивою FilesMatch.
  3. Веб-сервер передає запит до PHP-FPM через протокол FastCGI — або через Unix-сокет домену (/run/php/php8.2-fpm.sock), або через TCP-сокет (127.0.0.1:9000).
  4. Головний процес PHP-FPM маршрутизує запит до доступного воркера з налаштованого пулу.
  5. Воркер виконує PHP-скрипт, записує в stdout і повертає відповідь веб-серверу.
  6. Веб-сервер доставляє відрендерений HTML клієнту.
  7. Процес воркера не завершується — він повертається до пулу очікування, готовий до наступного запиту.

Unix-сокети є кращими за TCP для локальної комунікації, оскільки вони повністю обходять стек TCP/IP, зменшуючи затримку на 10–20% у бенчмарках та усуваючи накладні витрати на прив’язку портів і маршрутизацію через loopback.

Режими управління процесами

PHP-FPM підтримує три режими pm (менеджера процесів), і вибір неправильного є однією з найпоширеніших помилок неправильного налаштування.

pm = static

Фіксована кількість воркерів завжди працює незалежно від трафіку. Використовуйте це на виділених серверах, де потрібна передбачувана, попередньо виділена пам’ять і можна дозволити собі накладні витрати на простій.

pm = static
pm.max_children = 20

pm = dynamic

PHP-FPM запускає базову кількість воркерів і масштабується вгору або вниз у визначених межах. Це найбільш поширений режим і правильний стандарт для більшості середовищ VPS Хостингу.

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500

pm = ondemand

Воркери запускаються лише при надходженні запиту і завершуються після pm.process_idle_timeout секунд бездіяльності. Це мінімізує споживання пам’яті в режимі очікування та ідеально підходить для сайтів з низьким трафіком або спільних середовищ, де співіснують десятки пулів.

pm = ondemand
pm.max_children = 20
pm.process_idle_timeout = 10s

Критична пастка: ondemand вносить затримку холодного старту на перший запит після періоду бездіяльності. Для застосунків, чутливих до затримок, dynamic завжди є кращим вибором.

Правильний розрахунок pm.max_children

Саме тут більшість адміністраторів допускають дорогі помилки. Занадто високе значення pm.max_children призводить до вичерпання пам’яті та OOM kills; занадто низьке — до черги запитів і помилок 502 під навантаженням.

Правильна формула:

pm.max_children = (Available RAM for PHP) / (Average PHP worker memory usage)

Щоб знайти середню пам’ять воркера PHP:

ps --no-headers -o "rss,cmd" -C php-fpm8.2 | awk '{ sum+=$1 } END { printf "Average: %d MBn", sum/NR/1024 }'

На VPS з 2 GB RAM, де NGINX, MySQL та ОС споживають ~600 MB, у вас є приблизно 1 400 MB для PHP. Якщо кожен воркер використовує ~70 MB, безпечне значення pm.max_children становить 20. Ніколи не встановлюйте його навмання.

Встановлення PHP-FPM

Debian / Ubuntu

sudo apt update
sudo apt install php8.2-fpm
sudo systemctl enable php8.2-fpm
sudo systemctl start php8.2-fpm

CentOS / AlmaLinux / RHEL (з репозиторієм Remi)

sudo dnf install epel-release
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
sudo dnf module enable php:remi-8.2
sudo dnf install php-fpm
sudo systemctl enable php-fpm
sudo systemctl start php-fpm

Перевірте, що служба працює, та підтвердьте шлях до сокета:

sudo systemctl status php8.2-fpm
ls -la /run/php/

Налаштування пулів PHP-FPM

Основна конфігурація PHP-FPM знаходиться в /etc/php/8.2/fpm/php-fpm.conf, але окремі визначення пулів належать до /etc/php/8.2/fpm/pool.d/. На системах на базі RHEL файли пулів знаходяться в /etc/php-fpm.d/.

Кожен пул є ізольованим середовищем виконання. Запуск кількох PHP-застосунків на одному сервері — наприклад, сайту WordPress і Laravel API — означає створення окремих файлів пулів з окремими користувачами, шляхами до сокетів і обмеженнями ресурсів. Це правильна архітектура для мультитенантних налаштувань і значно безпечніша, ніж спільне використання одного пулу.

Приклад: конфігурація виробничого пулу

[myapp]
user = myapp
group = myapp

; Unix socket — always prefer this over TCP for local communication
listen = /run/php/myapp-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

; Process manager
pm = dynamic
pm.max_children = 30
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
pm.max_requests = 1000

; Slow log — log requests taking longer than 2 seconds
slowlog = /var/log/php-fpm/myapp-slow.log
request_slowlog_timeout = 2s

; Status and ping endpoints
pm.status_path = /fpm-status
ping.path = /fpm-ping

; Environment isolation
clear_env = yes
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin

; PHP value overrides per pool
php_admin_value[error_log] = /var/log/php-fpm/myapp-error.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 256M
php_admin_value[upload_max_filesize] = 64M
php_admin_value[post_max_size] = 64M

Директива clear_env = yes є критично важливим налаштуванням безпеки, яке часто ігнорується. Без неї PHP-воркери успадковують усі змінні середовища від головного процесу, потенційно витікаючи конфіденційні системні дані у $_ENV вашого застосунку.

Інтеграція PHP-FPM з NGINX

NGINX не має власних можливостей виконання PHP — він повністю покладається на FastCGI для делегування PHP-запитів. Це насправді є архітектурною перевагою: NGINX обробляє статичні файли практично без витрат, тоді як PHP-FPM обробляє лише те, що потребує виконання.

server {
    listen 80;
    server_name example.com;
    root /var/www/myapp/public;
    index index.php index.html;

    # Serve static files directly, no PHP involvement
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # Delegate PHP to PHP-FPM
    location ~ .php$ {
        # Security: prevent executing uploaded files as PHP
        try_files $uri =404;
        fastcgi_split_path_info ^(.+.php)(/.+)$;

        fastcgi_pass unix:/run/php/myapp-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;

        # Performance tuning
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_read_timeout 300;
    }

    # Block access to the FPM status page from public
    location ~ ^/(fpm-status|fpm-ping)$ {
        allow 127.0.0.1;
        deny all;
        fastcgi_pass unix:/run/php/myapp-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Примітка щодо безпеки: Рядок try_files $uri =404; перед fastcgi_pass є обов’язковим. Без нього NGINX буде пересилати запити для неіснуючих файлів до PHP-FPM, дозволяючи атаки обходу шляху, коли зловмисник завантажує зображення з PHP-кодом і змушує сервер його виконати.

Інтеграція PHP-FPM з Apache

Apache потребує mod_proxy_fcgi для зв’язку з PHP-FPM. На відміну від mod_php, цей підхід дозволяє Apache запускати PHP-FPM від імені окремого користувача, покращуючи ізоляцію.

sudo a2enmod proxy_fcgi setenvif
sudo systemctl restart apache2

Конфігурація віртуального хоста:

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/myapp/public

    <Directory /var/www/myapp/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    <FilesMatch ".php$">
        SetHandler "proxy:unix:/run/php/myapp-fpm.sock|fcgi://localhost/"
    </FilesMatch>

    ErrorLog ${APACHE_LOG_DIR}/myapp-error.log
    CustomLog ${APACHE_LOG_DIR}/myapp-access.log combined
</VirtualHost>

Увімкнення та використання сторінки статусу PHP-FPM

Вбудована сторінка статусу є одним із найменш використовуваних діагностичних інструментів PHP-FPM. Після налаштування pm.status_path у файлі пулу запитайте її безпосередньо:

sudo -u www-data SCRIPT_NAME=/fpm-status SCRIPT_FILENAME=/fpm-status REQUEST_METHOD=GET cgi-fcgi -bind -connect /run/php/myapp-fpm.sock

Або, що практичніше, через curl після відкриття на обмеженому внутрішньому ендпоінті:

curl http://127.0.0.1/fpm-status?full

Ключові метрики для моніторингу:

  • listen queue: Запити, що очікують вільного воркера. Будь-яке значення вище 0 при стабільному навантаженні означає, що pm.max_children занадто низьке.
  • active processes: Воркери, що наразі виконують PHP. Якщо це значення постійно дорівнює pm.max_children, ви досягли максимальної потужності.
  • slow requests: Накопичена кількість запитів, що перевищили request_slowlog_timeout. Зростаюче значення вказує на вузькі місця на рівні застосунку.

Використання slow log для налагодження продуктивності

Slow log фіксує повний стек викликів PHP для будь-якого запиту, що перевищує налаштований поріг. Це безцінно для виявлення проблем N+1 запитів, блокуючих I/O-викликів або неефективних циклів без необхідності використання повноцінного профілювальника.

slowlog = /var/log/php-fpm/myapp-slow.log
request_slowlog_timeout = 2s

Запис у slow log виглядає так:

[21-Jun-2025 14:32:11]  [pool myapp] pid 18432
script_filename = /var/www/myapp/public/index.php
[0x00007f3b4c001e80] PDOStatement->execute() /var/www/myapp/vendor/laravel/framework/src/Illuminate/Database/Connection.php:338
[0x00007f3b4c001d40] runQueryCallback() /var/www/myapp/vendor/laravel/framework/src/Illuminate/Database/Connection.php:295

Це одразу вказує, що вузьким місцем є запит до бази даних, а не логіка PHP — точно спрямовуючи ваші зусилля з оптимізації.

PHP-FPM з OPcache: необхідне поєднання

PHP-FPM сам по собі обробляє управління процесами; OPcache усуває витрати на розбір і компіляцію PHP-файлів при кожному запиті. Разом вони утворюють повний стек продуктивності для PHP на Linux.

Увімкніть і налаштуйте OPcache в /etc/php/8.2/fpm/php.ini або спеціальному /etc/php/8.2/fpm/conf.d/10-opcache.ini:

opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.revalidate_freq=0
opcache.validate_timestamps=0
opcache.jit_buffer_size=128M
opcache.jit=tracing

Встановлення validate_timestamps=0 вимикає перевірку змін файлів при кожному запиті — значний приріст продуктивності у виробничому середовищі. Коли ви розгортаєте новий код, явно запускайте скидання кешу:

sudo systemctl reload php8.2-fpm

На VPS з cPanel, налаштування OPcache часто доступні в інтерфейсі конфігурації PHP, але ручне налаштування через файли .ini завжди забезпечує більш тонкий контроль.

Посилення безпеки PHP-FPM

Запускайте кожен пул від імені виділеного системного користувача

Ніколи не запускайте пули PHP-FPM від імені root або спільного користувача www-data для кількох застосунків. Створіть виділеного системного користувача для кожного застосунку:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp

Потім встановіть user = myapp і group = myapp у конфігурації пулу. Це гарантує, що скомпрометований PHP-застосунок не зможе читати файли, що належать іншим застосункам на тому ж сервері.

Обмежте PHP-функції

У блоці php_admin_value пулу вимкніть функції, які не мають законного використання у веб-застосунках:

php_admin_value[disable_functions] = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

Обмежте open_basedir

Обмежте доступ PHP до файлів директорією застосунку:

php_admin_value[open_basedir] = /var/www/myapp:/tmp

Використовуйте Unix-сокети з суворими дозволами

TCP-сокети (127.0.0.1:9000) доступні будь-якому процесу на сервері. Unix-сокети з listen.mode = 0660 обмежують доступ лише для власника та групи.

Перевірка повного стеку

Після налаштування PHP-FPM і веб-сервера перевірте весь ланцюжок перед запуском у виробництво.

Перезавантажте всі служби:

sudo systemctl reload php8.2-fpm
sudo systemctl reload nginx
# or
sudo systemctl reload apache2

Перевірте синтаксис конфігурації NGINX перед перезавантаженням:

sudo nginx -t

Створіть тимчасовий інформаційний файл (видаліть його після перевірки — він розкриває конфіденційні дані сервера):

echo "<?php phpinfo();" | sudo tee /var/www/myapp/public/phpinfo.php

Відкрийте http://example.com/phpinfo.php у браузері та підтвердьте:

  • Server API показує FPM/FastCGI
  • PHP Version відповідає встановленій версії
  • Розділ OPcache присутній і увімкнений

Потім негайно видаліть файл:

sudo rm /var/www/myapp/public/phpinfo.php

PHP-FPM у мультизастосунковому та високонавантаженому середовищі

На Виділеному сервері, що хостить десятки PHP-застосунків, архітектура з кількома пулами стає необхідною. Кожен застосунок отримує власний пул з незалежно налаштованими pm.max_children, обмеженнями пам’яті та шляхами до slow log. Застосунок, що некоректно поводиться і вичерпує свій пул воркерів, не впливає на інші застосунки.

Для сценаріїв з високим трафіком поєднуйте PHP-FPM з:

  • NGINX FastCGI кешуванням (fastcgi_cache) для обслуговування кешованих PHP-відповідей як статичних файлів, повністю обходячи PHP-FPM для повторних запитів
  • Redis або Memcached для зберігання PHP-сесій, замінюючи стандартні файлові сесії, які створюють I/O-конкуренцію під навантаженням
  • Горизонтальне масштабування шляхом запуску PHP-FPM на серверах застосунків за балансувальником навантаження, з NGINX на окремому фронтенд-вузлі

Якщо ваш стек включає SSL-термінацію, поєднання PHP-FPM з правильно налаштованими SSL-сертифікатами на рівні NGINX гарантує, що TLS-рукостискання обробляються до того, як запити досягнуть PHP-FPM, дозволяючи PHP-воркерам зосередитися виключно на логіці застосунку.

Для обчислювально інтенсивних PHP-навантажень — виведення машинного навчання через PHP-прив’язки, обробка зображень або транскодування відео — розгляньте GPU Хостинг, де PHP-FPM може делегувати важкі обчислення бібліотекам з GPU-прискоренням, зберігаючи стандартну обробку запитів для веб-рівня.

Матриця ключових рішень і технічний чеклист

Перед розгортанням PHP-FPM у виробництві перевірте кожен пункт цього чеклиста:

Вибір менеджера процесів

  • Використовуйте pm = dynamic для загальних VPS-навантажень
  • Використовуйте pm = static лише на виділених серверах з передбачуваним, стабільним трафіком
  • Використовуйте pm = ondemand лише для пулів з низьким трафіком або розробки

Планування потужності

  • Виміряйте фактичну пам’ять воркера за допомогою ps перед встановленням pm.max_children
  • Зарезервуйте щонайменше 20% загальної RAM для ОС, веб-сервера та бази даних
  • Встановіть pm.max_requests між 500–1000 для запобігання накопиченню витоків пам’яті

Безпека

  • Кожен пул застосунку працює від імені власного системного користувача
  • clear_env = yes встановлено в кожному пулі
  • open_basedir обмежує доступ до файлів директорією застосунку
  • disable_functions блокує функції виконання оболонки
  • Використовуються Unix-сокети замість TCP-сокетів

Спостережуваність

  • pm.status_path налаштовано і доступно лише з localhost
  • slowlog увімкнено зі значенням request_slowlog_timeout 2–5 секунд
  • Ротація логів налаштована для всіх файлів логів PHP-FPM

Продуктивність

  • OPcache увімкнено з validate_timestamps=0 у виробничому середовищі
  • NGINX FastCGI кешування налаштовано для кешованих ендпоінтів
  • Обробник PHP-сесій встановлено на Redis або Memcached, а не файли

Операційні аспекти

  • sudo systemctl reload php8.2-fpm використовується для змін конфігурації без простою (не restart)
  • phpinfo.php видалено з кореневої директорії документів одразу після перевірки
  • Конфігурація пулу знаходиться під контролем версій разом з кодом застосунку

FAQ

У чому різниця між PHP-FPM та mod_php?

mod_php вбудовує інтерпретатор PHP в кожен процес воркера Apache, споживаючи пам’ять навіть при обслуговуванні статичних файлів і тісно пов’язуючи PHP з Apache. PHP-FPM працює як повністю окрема служба, спілкується через FastCGI, працює з будь-яким веб-сервером, включаючи NGINX, і дозволяє ізоляцію процесів для кожного застосунку з незалежними обмеженнями ресурсів.

Як вибрати між Unix-сокетом і TCP-сокетом для PHP-FPM?

Використовуйте Unix-сокет (listen = /run/php/app-fpm.sock), коли PHP-FPM і веб-сервер працюють на одній фізичній або віртуальній машині. Unix-сокети обходять стек TCP/IP, зменшуючи затримку та усуваючи конфлікти портів. Використовуйте TCP-сокет (listen = 127.0.0.1:9000) лише тоді, коли PHP-FPM працює на іншому хості, ніж веб-сервер.

Чому я отримую помилки 502 Bad Gateway під навантаженням?

Помилка 502 від NGINX, що вказує на PHP-FPM, майже завжди означає, що черга прослуховування заповнена — всі воркери зайняті і нові з’єднання відхиляються. Перевірте pm.status_path на ненульове значення listen queue. Виправлення полягає або у збільшенні pm.max_children (якщо дозволяє RAM), або в оптимізації повільних PHP-скриптів, виявлених через slow log.

Як перезавантажити PHP-FPM без переривання активних з’єднань?

Використовуйте sudo systemctl reload php8.2-fpm замість restart. Сигнал reload (SIGUSR2) змушує головний процес плавно перезапустити воркери: існуючі запити завершуються нормально, тоді як нові воркери підхоплюють оновлену конфігурацію. Жорстке restart негайно завершує всі воркери, перериваючи запити в обробці.

Чи може PHP-FPM одночасно запускати кілька версій PHP на одному сервері?

Так. Встановіть кілька версій PHP (наприклад, php7.4-fpm та php8.2-fpm) і налаштуйте кожен пул застосунку на використання відповідного шляху до сокета. У NGINX вкажіть fastcgi_pass на правильний сокет для кожного серверного блоку. Це стандартна практика на спільній інфраструктурі, що управляється через Панелі керування VPS, і повністю підтримується на VPS Хостингу з root-доступом.

Адміністрація
Linux Адміністрація
Linux Адміністрація

Заощадьте 15% на всіх хостингових послугах

Перевірте свої навички і отримайте Знижку на будь-який план хостингу

Використовуй код: Skills Почати
Швидкий доступ до інформації
Швидкий доступ до інформації

Заощаджуйте свій час і отримуйте швидку відповідь на своє запитання

Вирішуйте проблеми самостійно
Вирішуйте проблеми самостійно

База знань містить детальні інструкції, які дозволять вам самостійно вирішувати технічні завдання.

Вдосконалення навичок
Вдосконалення навичок

Використовуючи базу знань, ви розширюєте свої знання про веб-хостинг і пов'язані з ним теми

Ілюстрації та діаграми
Ілюстрації та діаграми

Багато статей супроводжуються ілюстраціями та діаграмами, що полегшує розуміння складних процесів та налаштувань.

Корисні хитрощі
Корисні хитрощі

Корисні поради для покращення роботи сайту або додатку

Актуальність наведених тем
Актуальність наведених тем

Інформація в базі знань регулярно оновлюється, щоб відображати останні зміни і тенденції в сфері IT-інфраструктури та сервісу AlexHost

Не знайшли потрібну тему? Є ідеальне рішення

Шановні гості та клієнти! Ваша зручність - наш пріоритет! Якщо у вас виникли труднощі з установкою певного програмного забезпечення або розгортанням сервера, будь ласка, не соромтеся звертатися до нас. Ми цінуємо вашу думку і завжди готові допомогти у вирішенні ваших проблем.

Більше того, ми надаємо вам можливість брати активну участь у створенні нашої бази знань. Якщо у вас є теми або питання, які ви хотіли б включити в нашу базу, дайте нам знати! Ми готові написати докладні статті та посібники, виходячи з ваших потреб.

Ми прагнемо зробити вашу роботу з AlexHost максимально зручною та ефективною, і ваш внесок у базу знань допомагає нам досягти цієї мети. Зв'яжіться з нами -> Контакти
info@alexhost.com і повідомте нам, як ми можемо зробити ваше перебування у нас ще кращим.

Solution Image