Установка PHP-FPM: настройка серверной обработки скриптов

Раздел: Администрирование сервера -> Управление службой 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

Как установить PHP-FPM - comments

En
установить php fpm (php)