Что такое PHP-FPM | Установка и настройка PHP-FPM
PHP-FPM — это менеджер процессов FastCGI, в котором заранее запущенные процессы-воркеры принимают PHP-запросы, переданные веб-сервером, и обрабатывают их. На сервере AlmaLinux 9 с Apache в этом руководстве проверяется, установлен ли он, как настроены пулы и сокеты для каждого сайта, а затем разбираются проверка конфигурации и проверка состояния на реальном выводе.
Apache может выполнять PHP и напрямую через mod_php, но если передать его PHP-FPM, веб-сервер и PHP разделяются. Nginx не умеет выполнять PHP напрямую, поэтому передаёт запросы процессу FastCGI, такому как PHP-FPM. Поэтому один PHP-FPM можно подключить и к Apache, и к Nginx. Настройки пула и устройство сокета ниже применимы без изменений и при связке PHP-FPM с Nginx.
1️⃣ Что такое PHP-FPM: чем CGI отличается от FastCGI
CGI (Common Gateway Interface) — стандартный способ, которым веб-сервер запускает внешнюю программу для создания динамического контента, и при каждом входящем запросе программа запускается заново. Затраты на создание и удаление процесса при каждом запросе накапливаются, поэтому чем больше обращений, тем медленнее отвечает сервер.
FastCGI убирает эти затраты: программа запускается заранее, и запросы обрабатываются один за другим. Это разница между компьютером, который включают и выключают при каждом использовании, и компьютером, который уже включён и сразу готов к работе. PHP-FPM (FastCGI Process Manager) — менеджер, который запускает PHP через FastCGI, и он входит в состав PHP начиная с версии 5.3.3.
Для каждого пула — группы воркеров — PHP-FPM заранее запускает заданное число воркеров; свободный воркер принимает запрос, который веб-сервер передал через сокет, обрабатывает его и ждёт следующий. Статические файлы, такие как изображения и CSS, веб-сервер отдаёт сам, и в PHP-FPM попадают только файлы PHP. Различается лишь то, как веб-сервер передаёт запросы в сокет: Apache использует модуль mod_proxy_fcgi, а Nginx — настройку fastcgi_pass.
2️⃣ Установка PHP-FPM: проверка пакета и установка через dnf
Если вы установили PHP через dnf на сервере семейства RHEL, пакет php-fpm установился вместе с ним. Сначала проверьте через rpm, установлен ли он. Установка PHP проходит так же, как в статье Установка APM в Rocky Linux.
rpm -qa | grep php-fpmphp-fpm-8.3.36-1.module_php.8.3.el9.remi.x86_64Если вывод пуст, пакет не установлен; установите его через dnf.
dnf -y install php-fpmКогда установка закончится, выполните ту же команду rpm ещё раз и убедитесь, что выводится имя пакета.
3️⃣ Настройка PHP-FPM: пул www.conf, сокет, статический и динамический режимы
Файлов конфигурации два: общая конфигурация [/etc/php-fpm.conf] и конфигурация пула [/etc/php-fpm.d/www.conf]. В пуле по умолчанию www.conf сначала смотрят строки listen и pm, а их значения сразу после установки такие.
grep -E '^(listen|pm) ' /etc/php-fpm.d/www.conflisten = /run/php-fpm/www.sock
pm = dynamiclisten — это место, куда веб-сервер передаёт запросы, а значение по умолчанию в версии 8.3 — сокет Unix [/run/php-fpm/www.sock]. Значение по умолчанию в старых версиях, [127.0.0.1:9000], принимает запросы через TCP-порт. Внутри одного сервера сокет легче, потому что не проходит этап соединения через порт, а с помощью listen.owner и listen.group доступ можно ограничить так же, как правами на файлы.
🔲 Настройка статического и динамического режимов
pm — это способ запуска воркеров, и в нём указывают один из трёх вариантов: static, dynamic или ondemand. Статический режим всегда держит запущенным то количество, которое записано в pm.max_children, и настройка ниже поддерживает 100 воркеров.
pm = static
pm.max_children = 100Динамический режим включён по умолчанию и увеличивает или уменьшает число воркеров в зависимости от количества запросов. Настройка ниже запускает 12 воркеров при старте, держит от 6 до 18 свободных и увеличивает их число максимум до 120.
pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18Режим ondemand запускает воркеры только при поступлении запроса и завершает их, когда проходит pm.process_idle_timeout, поэтому он подходит сайтам с небольшим трафиком и не подходит сайтам с большим трафиком.
Три режима различаются тем, когда они запускают воркеры и как меняется их число.
| Режим | Как запускаются воркеры | Подходящие сайты |
|---|---|---|
| static (статический) | Всегда держит запущенным то количество, которое записано в pm.max_children | Сайты с большим трафиком |
| dynamic (динамический) | По умолчанию · число меняется в пределах pm.start_servers, pm.min_spare_servers и pm.max_spare_servers в зависимости от количества запросов | Сайты, у которых трафик то растёт, то падает |
| ondemand | Запускает только при поступлении запроса и завершает, когда проходит pm.process_idle_timeout | Сайты с небольшим трафиком |
max_children определяют, разделив память сервера на память, которую использует один воркер. Даже когда накапливаются предупреждения о достижении [max_children], не повышайте значение сразу, а сначала по логам выясните, какие запросы заполнили воркеры.
Лимиты памяти и загрузки задают в php.ini — общей конфигурации PHP — и подбирают вместе с числом воркеров под сайт, который вы ведёте.
memory_limit = 1024M
post_max_size = 128M
upload_max_filesize = 128MЭти три значения — предел памяти для одного скрипта PHP и размер файлов, которые можно загрузить за один раз, и они вступают в силу только после перезапуска PHP-FPM.
🔲 Настройка пула для каждого аккаунта сайта
Если сайтов несколько, не используйте один общий www.conf, а создайте для каждого аккаунта отдельный файл пула и разделите аккаунт запуска и сокет. PHP одного сайта не сможет читать файлы другого аккаунта, а число воркеров задаётся для каждого сайта отдельно.
vi /etc/php-fpm.d/siteuser.confВ файле указывают имя пула, аккаунт запуска, путь к сокету и число воркеров.
[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 и listen.group — владелец и группа файла сокета, и PHP-FPM создаёт сокет с этими значениями при запуске. Если веб-сервер работает под аккаунтом nobody, впишите в listen.group значение nobody, а если под аккаунтом apache — apache, чтобы веб-сервер мог открыть сокет.
listen.owner = siteuser
listen.group = nobody
listen.mode = 0660Эти три строки есть в каждом файле пула, и после изменения значений нужен перезапуск, чтобы сокет был создан заново с новыми правами.
🔲 Настройка slowlog
slowlog — файл, в который записывается место выполнения запросов, шедших дольше request_slowlog_timeout, и при значении 0 запись не ведётся. Когда ищете причину медленных запросов, включите его, указав время в секундах, например 3s.
slowlog = /var/log/php-fpm/www-slow.log
request_slowlog_timeout = 0В записанном файле остаются путь к скрипту медленного запроса и функция, которая выполнялась в тот момент, так что можно понять, какой плагин или код тормозил работу.
4️⃣ Связка с Apache: настройка VirtualHost и права сокета
Apache передаёт запросы к файлам PHP в сокет пула с помощью модуля mod_proxy_fcgi. В FilesMatch внутри VirtualHost добавляют одну строку SetHandler, а для каждого сайта указывают сокет его аккаунта.
# Один VirtualHost на аккаунт сайта · в SetHandler указывается сокет этого аккаунта (вместо SetHandler можно подключиться и через 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 и Directory — корневая папка сайта этого аккаунта, а -Indexes в Options не даёт показывать список папок в браузере.
🔲 Настройка прав сокета
Когда пул запускается, сокет создаётся со значениями listen.owner, listen.group и listen.mode, а через ls вы проверяете, правильные ли права.
ls -l /run/php-fpm/итого 4
srw-rw---- 1 siteuser_a nobody 0 окт 22 23:34 siteuser_a.sock
-rw-r--r-- 1 root root 7 окт 26 03:00 php-fpm.pid
srw-rw---- 1 siteuser_b nobody 0 окт 22 23:34 siteuser_b.sock
srw-rw----+ 1 root root 0 окт 22 23:34 www.sockЕсли права не совпадают и веб-сервер не может открыть сокет, посетители получают ошибку 503; чтобы исправить это сразу, без перезапуска, задайте владельца и права через chown и chmod.
Это текущий синтаксис, в котором пользователя и группу разделяет двоеточие.
chown siteuser:nobody /run/php-fpm/siteuser.sockПосле смены владельца установите права 660.
chmod 660 /run/php-fpm/siteuser.sockЭто старый синтаксис, в котором пользователя и группу разделяет точка, и chown в AlmaLinux 9 по-прежнему выполняет его как есть.
chown siteuser.nobody /run/php-fpm/siteuser.sockПосле смены владельца установите права 660.
chmod 660 /run/php-fpm/siteuser.sockРезультат у двух синтаксисов одинаковый: каким бы вы ни воспользовались, владельцем сокета станет siteuser, а группой — nobody.
🔲 Связка с Nginx: настройка fastcgi_pass
В Nginx блок location для файлов PHP внутри блока server передаёт запросы в сокет того же пула через fastcgi_pass.
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php-fpm/siteuser.sock;
}Если Nginx работает под аккаунтом nginx, в файле пула в listen.group нужно записать nginx, чтобы он мог открыть сокет.
5️⃣ Проверка конфигурации и перезапуск: php-fpm -t и systemctl
После изменения конфигурации не перезапускайте сразу, а сначала проверьте синтаксис командой php-fpm -t. Если в файле пула опечатка, при перезапуске падает весь PHP-FPM, и все сайты получают 503.
php-fpm -t[26-Oct-2026 17:33:45] NOTICE: configuration file /etc/php-fpm.conf test is successfulЕсли проверка пройдена, выводится сообщение [test is successful] вместе с путём к файлу конфигурации, и после этого вы применяете изменение в PHP-FPM. Изменения, при которых сокет нужно создать заново, например путь к сокету или listen.owner, применяют через restart. Если на работающем сервере вы изменили только значения вроде числа воркеров, применяйте через reload.
systemctl restart php-fpmЕсли вы правили VirtualHost, перезапустите и Apache.
systemctl restart httpdЗарегистрируйте службу через enable, чтобы она запускалась автоматически при повторном включении сервера.
systemctl enable php-fpmЗарегистрирована ли служба, проверяют через is-enabled.
systemctl is-enabled php-fpmenabledЧерез status проверяют, работают ли воркеры в каждом пуле.
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"
окт 26 03:00:01 server.example.com systemd[1]: Reloading The PHP FastCGI Process Manager...
окт 26 03:00:01 server.example.com systemd[1]: Reloaded The PHP FastCGI Process Manager.В строке Status значения active и idle — это воркеры, которые обрабатывают запросы сейчас, и свободные воркеры, а CGroup перечисляет воркеры по именам пулов. Имя хоста и имена пулов в выводе заменены на примерные значения.
🔢 FAQ & рекомендуемые материалы
Кеш
Кеш: определение и все области, где используется кеширование
По областям объясняет, как запросы, попавшие в кеш, вообще не доходят до воркера PHP-FPM.
Сервер кеша
Установка и настройка Varnish Cache для Apache и Nginx
Шаги установки, при которых сервер кеша ставят перед веб-сервером, чтобы сократить сами запросы PHP.
Linux
Команды Linux: 15 категорий
Таблица, в которой команды разложены по 15 категориям, включая rpm, grep и systemctl, использованные в этой статье.
ℹ️ О партнёрских ссылках
Материалы этого сайта содержат партнёрские ссылки. Если посетитель покупает товар или услугу по такой ссылке, сайт получает комиссию от продавца. При этом сумма, которую платит покупатель (при акционных скидках сумма снижается ↓), не увеличивается. Указанные цены, скидки и наличие актуальны на момент написания и могут отличаться, поэтому перед покупкой уточняйте их у продавца. Товары выбираются и оцениваются по нашим собственным критериям, а комиссия не влияет ни на порядок, ни на содержание обзоров.