Установка PHP-FPM: настройка серверной обработки скриптов
Основные способы установки PHP-FPM
PHP-FPM (FastCGI Process Manager) это альтернативная реализация FastCGI для PHP с расширенными возможностями управления процессами. Установка через пакетный менеджер является наиболее простым и рекомендуемым способом. На Debian/Ubuntu выполняется команда sudo apt update && sudo apt install php-fpm (или конкретная версия, например php8.1-fpm). После установки служба автоматически запускается. Проверить состояние можно командой sudo systemctl status php8.1-fpm. Основные файлы конфигурации: /etc/php/8.1/fpm/php-fpm.conf (глобальная) и пулы в /etc/php/8.1/fpm/pool.d/www.conf. Для базовой настройки пула достаточно изменить параметры listen, user, group, pm. После изменений используйте sudo systemctl reload php8.1-fpm.
Типичные ошибки и их решение
- Ошибка: "listen.owner = www-data" не существует. Решение: создайте пользователя www-data или измените владельца на существующего (например, nginx).
- Ошибка: "bind failed: Address already in use". Возникает если TCP-порт (например, 9000) занят. Решение: изменить порт в
listen = 127.0.0.1:9001или остановить другой процесс. - Ошибка: "failed to open configuration file". Если отсутствует файл пула. Решение: создать пул по умолчанию или скопировать из
/etc/php/8.1/fpm/pool.d/www.conf.default.
Как установить PHP-FPM конкретной версии (например 7.4) на Ubuntu?
Для установки версии, отличной от версии из репозитория по умолчанию, используется PPA ppa:ondrej/php. Подключите репозиторий, обновите список пакетов и установите нужную версию:
sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt install php7.4-fpm php7.4-commonустановить php fpm (как установить php-fpm)
После установки можно запустить службу и проверить версию.
Возможная проблема:
Конфликт с уже установленной версией PHP. Решение: установите только одну версию или используйте разные сокеты и порты.
Как собрать PHP-FPM из исходного кода с нестандартными опциями?
Компиляция позволяет включить специфические расширения и оптимизации. Скачайте исходный код с php.net, распакуйте и выполните:
./configure --enable-fpm --with-mysqli --with-pdo-mysql --with-opcache --enable-mbstring --enable-zip --with-gd --prefix=/usr/local/php8.2
make -j$(nproc)
sudo make install
Скопируйте конфигурационные файлы из /usr/local/php8.2/etc/php-fpm.conf.default и настройте пул.
Ошибка: отсутствуют зависимости (libxml2, libssl-dev и др.).
Решение: установите недостающие пакеты с помощью sudo apt install libxml2-dev libssl-dev libcurl4-openssl-dev и повторите ./configure.
Как настроить пул с Unix-сокетом для повышенной безопасности?
Использование сокетов вместо TCP исключает сетевые атаки. В файле пула укажите:
listen = /run/php/php8.1-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
Перезагрузите службу и настройте сервер (например, nginx) на соединение через этот сокет.
Ошибка: nginx не может подключиться к сокету (permission denied).
Решение: проверьте, что пользователь веб-сервера входит в группу, указанную в listen.group, или измените listen.mode на 0666 (менее безопасно).
Как включить страницу статистики PHP-FPM (status page)?
Добавьте в пул параметры:
pm.status_path = /status
ping.path = /ping
ping.response = pong
В конфигурации nginx создайте обработчик:
location ~ ^/(status|ping)$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
allow 127.0.0.1;
deny all;
}
После перезагрузки nginx и PHP-FPM проверьте curl http://localhost/status.
Ошибка: 404 или пустой ответ.
Убедитесь, что pm.status_path задан именно в активном пуле, а не в глобальном конфиге. Перезагрузите PHP-FPM.
Как настроить несколько пулов для разных сайтов с разными пользователями?
Скопируйте www.conf в файлы для каждого сайта, например site1.conf и site2.conf. В каждом измените listen (уникальный сокет или порт), user, group, pm.*. Пример:
[site1]
user = site1user
group = site1user
listen = /run/php/site1.sock
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
В nginx для каждого виртуального хоста укажите соответствующий fastcgi_pass.
Проблема: пулы не запускаются из-за конфликта сокетов.
Убедитесь, что пути сокетов уникальны и не заняты другими процессами. Проверьте права на директорию /run/php.
Как использовать разные версии PHP для разных виртуальных хостов?
Установите несколько версий PHP-FPM (например, php7.4-fpm и php8.1-fpm). Каждая из них создаёт свой сокет (по умолчанию /run/php/php7.4-fpm.sock и /run/php/php8.1-fpm.sock). В конфигурации nginx для каждого сайта укажите:
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
или
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
Ошибка: одна из служб не запущена.
Проверьте статус каждой службы: sudo systemctl status php7.4-fpm. Включите автозапуск.
Как настроить режим pm = ondemand для экономии памяти?
Режим ondemand порождает процессы только при поступлении запросов. Укажите в пуле:
pm = ondemand
pm.max_children = 50
pm.process_idle_timeout = 10s
Процессы будут завершаться после простоя в 10 секунд.
Недостаток: задержка при первом запросе после простоя.
Решение: использовать pm = dynamic с минимальным числом idle-процессов.
Как включить логирование медленных запросов (slow log)?
Добавьте в пул:
request_slowlog_timeout = 5s
slowlog = /var/log/php-slow.log
После перезагрузки все запросы, выполняющиеся дольше 5 секунд, будут записываться в указанный файл.
Лог не создаётся.
Проверьте права на директорию /var/log/ и пользователя, от которого работает PHP-FPM. Создайте файл заранее с нужными правами.
Расширенные примеры настройки PHP-FPM
Пример 1: Конфигурация пула для высоконагруженного сервера
Для большого трафика используется режим dynamic с большим числом процессов. Файл /etc/php/8.1/fpm/pool.d/www.conf:
[www]
user = www-data
group = www-data
listen = /run/php/php8.1-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 150
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.status_path = /status
ping.path = /ping
request_terminate_timeout = 30s
request_slowlog_timeout = 5s
slowlog = /var/log/php-slow.log
После перезагрузки проверьте статус:
● php8.1-fpm.service - PHP 8.1 FastCGI Process Manager
Loaded: loaded /lib/systemd/system/php8.1-fpm.service
Active: active (running)
Main PID: 12345 (php-fpm8.1)
Tasks: 22 (limit: 2345)
Memory: 89.0M
CPU: 2.345s
CGroup: /system.slice/php8.1-fpm.service
Пример 2: Компиляция PHP-FPM с расширенными опциями
Сборка с поддержкой OPcache, GD, MySQL, mbstring, ZIP и отключением неиспользуемых модулей:
./configure --enable-fpm --with-mysqli --with-pdo-mysql \
--with-opcache --enable-mbstring --enable-zip \
--with-gd --with-freetype-dir --with-jpeg-dir \
--with-png-dir --disable-cgi --disable-phpdbg \
--prefix=/usr/local/php8.2
make -j$(nproc) && sudo make install
Результат: бинарник /usr/local/php8.2/sbin/php-fpm. Проверка версии:
$ /usr/local/php8.2/sbin/php-fpm -v
PHP 8.2.0 (fpm-fcgi) (built: Jan 15 2025 10:00:00)
Copyright (c) The PHP Group
Zend Engine v4.2.0, Copyright (c) Zend Technologies
with Zend OPcache v8.2.0
Пример 3: Включение статусной страницы с выводом в JSON
В пуле задано pm.status_path = /status. В nginx добавлен location. Запрос через curl:
curl -s 'http://localhost/status?json'
Результат (JSON):
{
"pool": "www",
"process manager": "dynamic",
"start time": "2025-01-15 12:00:00",
"start since": 3600,
"accepted conn": 12345,
"listen queue": 0,
"max listen queue": 0,
"listen queue len": 128,
"idle processes": 8,
"active processes": 12,
"total processes": 20,
"max active processes": 25,
"max children reached": 0,
"slow requests": 0
}
Пример 4: Настройка chroot для изоляции пула
Создайте минимальную файловую структуру внутри /var/chroot:
sudo mkdir -p /var/chroot/{bin,dev,etc,lib,usr,var}
sudo cp /bin/sh /var/chroot/bin/
sudo mknod /var/chroot/dev/null c 1 3
# копирование необходимых библиотек (ldd /bin/sh)
В конфигурации пула укажите:
chroot = /var/chroot
chdir = /
Теперь PHP-FPM будет работать в изолированном окружении.
Пример 5: Интеграция PHP-FPM с Apache через mod_proxy_fcgi
Установите модуль:
sudo a2enmod proxy_fcgi
sudo systemctl restart apache2
В виртуальном хосте Apache добавьте:
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/var/www/html/$1
Перезагрузите Apache. Запросы на PHP-файлы будут перенаправлены на PHP-FPM.
Пример 6: Настройка нескольких пулов с разными сокетами для одного сервера
Создайте два файла конфигурации пулов: /etc/php/8.1/fpm/pool.d/site1.conf и site2.conf:
[site1]
user = site1
listen = /run/php/site1.sock
pm = dynamic
pm.max_children = 10
[site2]
user = site2
listen = /run/php/site2.sock
pm = dynamic
pm.max_children = 20
В nginx для каждого сервера:
fastcgi_pass unix:/run/php/site1.sock;
Проверьте, что оба сокета созданы:
$ ls -la /run/php/ srw-rw---- 1 site1 site1 0 Jan 15 12:00 site1.sock srw-rw---- 1 site2 site2 0 Jan 15 12:00 site2.sock