Страница 1 из 1

Настройка nginx php-fpm: лучшие практики и production-ready конфиг

Добавлено: 11 май 2026, 18:19
admin
Изображение

Архитектурные принципы взаимодействия Nginx и PHP-FPM

В современной высоконагруженной веб-инфраструктуре разделение ролей между веб-сервером и интерпретатором языка является стандартом де-факто. Nginx, работая в качестве обратного прокси, берет на себя задачи терминирования SSL-соединений, отдачи статического контента (изображения, стили, скрипты), кширования и балансировки нагрузки. Обработка динамического PHP-кода делегируется менеджеру процессов FastCGI — PHP-FPM (FastCGI Process Manager).

Взаимодействие между компонентами происходит по протоколу FastCGI — бинарному протоколу, который позволяет передавать данные между веб-сервером и независимым приложением более эффективно по сравнению с устаревшим CGI. Основное преимущество такой связки заключается в том, что PHP-FPM поддерживает пул постоянно запущенных воркеров, готовых к немедленной обработке запроса, что исключает накладные расходы на запуск интерпретатора при каждом обращении.

Выбор транспортного уровня: Unix Domain Sockets против TCP/IP

Существует два основных способа настройки канала связи между Nginx и PHP-FPM. Выбор зависит от топологии сети и требований к производительности.
  • Unix Domain Sockets (UDS): Оптимальный выбор, если Nginx и PHP-FPM запущены на одном физическом или виртуальном хосте. Передача данных происходит внутри ядра ОС без задействования сетевого стека, что снижает задержки и нагрузку на процессор.
  • TCP/IP Sockets: Необходимы, когда сервисы разнесены по разным серверам или контейнерам. Позволяют масштабировать PHP-FPM горизонтально, выделяя отдельные вычислительные узлы под интерпретацию кода.
При использовании Unix-сокетов путь в конфигурации выглядит как unix:/var/run/php/php8.2-fpm.sock. Для TCP-соединений используется формат 127.0.0.1:9000. Стоит помнить, что при работе через сокеты необходимо следить за правами доступа к файлу сокета, чтобы пользователь, от имени которого запущен Nginx, имел права на чтение и запись.

Базовая конфигурация блока server

Для настройки проксирования необходимо описать обработку файлов с расширением .php внутри блока location. Типовая конфигурация выглядит следующим образом:

Код: Выделить всё

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

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        
        # Защита от передачи пустых имен скриптов
        try_files $fastcgi_script_name =404;
    }
}
Директива fastcgi_param SCRIPT_FILENAME является критически важной, так как она сообщает PHP-FPM, какой именно файл на диске должен быть исполнен. Без правильной передачи этого параметра интерпретатор вернет ошибку "Primary script unknown".

Оптимизация производительности и буферизация

По умолчанию Nginx буферизует ответы от FastCGI-сервера. Это позволяет освободить процесс PHP-FPM сразу после того, как он передал данные в Nginx, не дожидаясь, пока медленный клиент получит ответ по сети. Однако при передаче очень больших объемов данных или стриминге настройки требуют корректировки.

Ключевые параметры тюнинга:
  • fastcgi_buffers: Определяет количество и размер буферов для одного запроса. Например,

    Код: Выделить всё

    fastcgi_buffers 16 16k;
    выделит до 256 КБ в памяти.
  • fastcgi_buffer_size: Размер буфера для чтения первой части ответа (заголовков).
  • fastcgi_read_timeout: Время ожидания ответа от PHP-FPM. Если скрипт выполняется долго (генерация тяжелых отчетов), это значение нужно увеличить (например, до 300s), чтобы избежать ошибки 504 Gateway Timeout.
  • fastcgi_keep_conn: Включение этой опции позволяет держать соединение с FastCGI-сервером открытым, что снижает нагрузку на создание TCP-сессий при высокой интенсивности запросов.
Безопасность и обработка путей

Одной из классических проблем безопасности является попытка выполнения произвольного кода через манипуляцию путями в запросе. Если в php.ini включен параметр cgi.fix_pathinfo=1, злоумышленник может загрузить картинку с внедренным PHP-кодом и обратиться к ней как к /upload/image.jpg/index.php, что заставит интерпретатор выполнить код из картинки.

Для предотвращения подобных атак на уровне Nginx следует:
  • Использовать директиву

    Код: Выделить всё

    try_files $uri =404;
    внутри блока обработки PHP.
  • Установить

    Код: Выделить всё

    cgi.fix_pathinfo=0
    в глобальных настройках PHP.
  • Ограничить выполнение скриптов только в определенных директориях, запретив выполнение в папках для загрузки пользовательских файлов.
Пример ограничения прав:
Любые запросы к PHP-файлам в директориях /uploads/ или /temp/ должны блокироваться директивой deny all или обрабатываться как статика без передачи в FastCGI.
Мониторинг и диагностика

Для глубокого анализа взаимодействия систем рекомендуется включить страницу статуса PHP-FPM. Для этого в конфигурации пула PHP-FPM (обычно www.conf) раскомментируется строка

Код: Выделить всё

pm.status_path = /status
. В Nginx добавляется соответствующий location:

Код: Выделить всё

location ~ ^/(status|ping)$ {
    allow 127.0.0.1;
    allow 192.168.1.100; # IP администратора
    deny all;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/var/run/php/php-fpm.sock;
    include fastcgi_params;
}
Это позволяет в реальном времени видеть количество активных процессов, длину очереди (listen queue) и общее число обработанных запросов. Если очередь растет, это сигнализирует о необходимости увеличения количества воркеров в настройках pm.max_children или об оптимизации самого PHP-кода.

Дополнительно, использование X-Forwarded-For и других HTTP-заголовков в fastcgi_params гарантирует, что PHP-приложение будет получать реальный IP-адрес клиента, а не адрес прокси-сервера, что критично для логирования и систем защиты от перебора паролей.