Представь, что ты развертываешь PHP-приложение на сервере. Ты установил nginx, но он не умеет исполнять PHP-код напрямую. Вот здесь на сцену выходит PHP-FPM — менеджер процессов FastCGI, который становится мостом между веб-сервером и интерпретатором PHP. Давай разберем, как правильно настроить эту связку для максимальной производительности и стабильности.
Что такое PHP-FPM и зачем он нужен с nginx
В отличие от Apache с модулем mod_php, nginx работает по другому принципу. Он не встраивает интерпретатор PHP в себя, а делегирует обработку PHP-скриптов внешнему процессу через FastCGI протокол. PHP-FPM (FastCGI Process Manager) — это именно тот демон, который управляет пулом PHP-процессов.
Установка компонентов
Начнем с базовой установки. В зависимости от дистрибутива Linux команды могут немного отличаться.
Для Ubuntu/Debian
sudo apt update
sudo apt install nginx php-fpm php-cli php-common php-mysql php-curl php-gd php-mbstring
Для CentOS/RHEL
sudo yum install epel-release
sudo yum install nginx php-fpm php-cli php-common php-mysqlnd php-curl php-gd php-mbstring
nginx -v и php-fpm -v. Убедись, что все необходимые PHP-расширения установлены для твоего приложения.
Базовая конфигурация PHP-FPM
Основной файл конфигурации PHP-FPM обычно находится в /etc/php/{version}/fpm/pool.d/www.conf или /etc/php-fpm.d/www.conf. Давай настроим пул процессов.
[www]
user = www-data
group = www-data
listen = /run/php/php8.1-fpm.sock
; Или через TCP: listen = 127.0.0.1:9000
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
slowlog = /var/log/php-fpm/slow.log
request_slowlog_timeout = 5s
php_admin_value[error_log] = /var/log/php-fpm/error.log
php_admin_flag[log_errors] = on
Объяснение ключевых параметров
| Параметр | Значение | Описание |
|---|---|---|
pm |
dynamic | Динамическое управление процессами (рекомендуется) |
pm.max_children |
50 | Максимальное количество PHP-процессов |
pm.max_requests |
500 | Перезапуск процесса после N запросов (против утечек памяти) |
Настройка nginx для работы с PHP-FPM
Теперь настроим виртуальный хост в nginx, который будет передавать PHP-запросы нашему FPM-демону.
server {
listen 80;
server_name example.com www.example.com;
root /var/www/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# Безопасность и производительность
fastcgi_buffer_size 128k;
fastcgi_buffers 256 16k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
}
location ~ /(\.ht|README|LICENSE|CHANGELOG|composer\.json|\.git) {
deny all;
}
# Статические файлы
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
}
Критически важные директивы
fastcgi_pass— указывает на socket или адрес PHP-FPMfastcgi_param SCRIPT_FILENAME— абсолютный путь к исполняемому PHP-файлуtry_files $uri =404— защита от произвольного выполнения кода- Буферы FastCGI — предотвращают ошибки 502 Bad Gateway при больших ответах
Проверка и запуск конфигурации
Перед перезапуском сервисов всегда проверяй конфигурационные файлы на ошибки.
# Проверка конфигурации nginx
sudo nginx -t
# Если все OK, перезагрузи nginx
sudo systemctl reload nginx
# Проверка конфигурации PHP-FPM
sudo php-fpm8.1 -t
# Перезапуск PHP-FPM
sudo systemctl restart php8.1-fpm
# Проверь статус сервисов
sudo systemctl status nginx php8.1-fpm
Создание тестового PHP-файла
Создай файл /var/www/html/info.php для проверки работы связки:
<?php
phpinfo();
?>
sudo rm /var/www/html/info.php. Он раскрывает чувствительную информацию о сервере.
Оптимизация производительности
После базовой настройки можно заняться оптимизацией. Вот ключевые параметры для тюнинга.
Оптимизация PHP-FPM пула
; /etc/php/8.1/fpm/pool.d/www.conf
pm = dynamic
; Формула для max_children: (RAM - 1GB) / Средний размер процесса PHP
pm.max_children = 80
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 40
; Ускорение загрузки OpCache
php_admin_value[opcache.preload] = /var/www/html/preload.php
php_admin_value[opcache.preload_user] = www-data
; Лимиты
php_admin_value[memory_limit] = 256M
php_admin_value[max_execution_time] = 30
php_admin_value[upload_max_filesize] = 64M
php_admin_value[post_max_size] = 64M
Оптимизация nginx для FastCGI
# В блоке http или server
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=phpcache:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout updating http_500 http_503;
fastcgi_cache_valid 200 301 302 60m;
fastcgi_cache_valid 404 1m;
# В location ~ \.php$
fastcgi_cache phpcache;
fastcgi_cache_bypass $http_cache_control;
fastcgi_no_cache $http_cache_control;
add_header X-Cache $upstream_cache_status;
Решение частых проблем
Давай разберем наиболее распространенные ошибки и их решения.
502 Bad Gateway
Самая частая ошибка. Причины и решения:
- PHP-FPM не запущен:
sudo systemctl start php8.1-fpm - Неверный путь к socket: проверь
listenв www.conf иfastcgi_passв nginx - Недостаточно процессов: увеличь
pm.max_children - Проблемы с правами:
sudo chown www-data:www-data /run/php/php8.1-fpm.sock
Файлы PHP скачиваются, а не исполняются
Nginx не обрабатывает PHP-файлы через FastCGI. Проверь:
- Наличие блока
location ~ \.php$в конфиге nginx - Правильность пути в
fastcgi_param SCRIPT_FILENAME - Что index.php указан в директиве
index
Ошибки прав доступа
# Правильные права для веб-директории
sudo chown -R www-data:www-data /var/www/html
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;
# Права на socket PHP-FPM
sudo chown www-data:www-data /run/php/php8.1-fpm.sock
sudo chmod 660 /run/php/php8.1-fpm.sock
Мониторинг и логи
Для отладки и мониторинга используй эти команды:
# Просмотр логов nginx
sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log
# Логи PHP-FPM
sudo tail -f /var/log/php8.1-fpm.log
sudo tail -f /var/log/php-fpm/slow.log # медленные запросы
# Статус пула процессов
sudo systemctl status php8.1-fpm
sudo ps aux | grep php-fpm
# Проверка соединения с socket
sudo ls -la /run/php/php8.1-fpm.sock
sudo ss -lnp | grep php-fpm
Часто задаваемые вопросы (FAQ)
Socket или TCP: что лучше использовать?
Socket (Unix domain socket) обычно быстрее на одном сервере, так как не использует сетевой стек. TCP (127.0.0.1:9000) удобнее при распределенной архитектуре, когда PHP-FPM работает на отдельном сервере. Для single-server выбирай socket.
Как рассчитать оптимальное значение pm.max_children?
Используй формулу: (Общая RAM - RAM для системы и других сервисов) / Средний размер процесса PHP. Узнай размер процесса: ps -ylC php-fpm8.1 --sort:rss. Например, при 4GB RAM и процессе 50MB: (4096 - 1024) / 50 ≈ 61 процесс.
Нужно ли настраивать несколько пулов PHP-FPM?
Да, если у тебя несколько сайтов с разными требованиями. Создай отдельный конфиг в /etc/php/8.1/fpm/pool.d/ для каждого сайта с разными настройками пользователей, процессов и лимитов.
Как защитить конфигурацию от распространенных атак?
1. Отключи опасные функции в php.ini: disable_functions = exec,passthru,shell_exec,system
2. Используй open_basedir для ограничения доступа к файлам
3. Настрой правильные права на socket (660)
4. Регулярно обновляй PHP и nginx
Краткий чек-лист настройки
- Установил nginx и PHP-FPM с необходимыми расширениями
- Настроил пул процессов в
www.confс оптимальными параметрами - Создал виртуальный хост nginx с правильным
fastcgi_pass - Проверил конфигурации и перезапустил сервисы
- Настроил права доступа для веб-директории и socket
- Включил кэширование FastCGI для производительности
- Настроил мониторинг через логи и системные команды
Правильная настройка связки nginx + PHP-FPM — это баланс между производительностью, стабильностью и безопасностью. Начни с базовой конфигурации из этого руководства, затем мониторь метрики и тонко настраивай параметры под конкретную нагрузку твоего приложения. Помни: оптимальные настройки зависят от твоих ресурсов сервера и характеристик PHP-приложения.