← Назад к блогу

Как работает связка Nginx и PHP-FPM

Когда браузер запрашивает PHP-страницу, Nginx не исполняет PHP-код сам. Он принимает HTTP-запрос, решает, как его обработать, и при необходимости передаёт выполнение отдельному процессу — PHP-FPM.

Коротко: Nginx отвечает за веб-трафик и статические файлы, PHP-FPM управляет PHP-процессами, а приложение формирует содержимое ответа.

Роли компонентов

Nginx слушает HTTP-порт, раздаёт CSS, JavaScript, изображения и другие готовые файлы. Динамический запрос он направляет в PHP-FPM.

PHP-FPM — FastCGI Process Manager. Он заранее держит пул PHP-процессов, принимает задания от веб-сервера и возвращает результат выполнения скрипта.

PHP-приложение разбирает запрос на уровне маршрутизации, выполняет нужный сценарий и создаёт ответ. В Symfony входной точкой служит public/index.php.

Путь запроса

Браузер
   ↓ HTTP
Nginx
   ↓ FastCGI
PHP-FPM
   ↓
public/index.php → приложение
   ↓
HTTP-ответ возвращается по той же цепочке

Для существующего файла, например /assets/app.js, Nginx отдаст его напрямую. Для адреса /blog файла на диске нет, поэтому запрос попадёт во фронт-контроллер приложения.

Зачем нужен FastCGI

FastCGI — протокол обмена между веб-сервером и процессом приложения. Nginx передаёт не только тело запроса, но и параметры окружения: HTTP-метод, строку запроса, имя исполняемого скрипта и другие данные.

Связь можно организовать через TCP-порт или Unix-сокет. Сокет удобен, когда Nginx и PHP-FPM находятся в одной системе. TCP нужен, если процессы работают в разных контейнерах или на разных узлах.

СпособКогда использовать
Unix-сокетNginx и PHP-FPM работают в одной системе
TCPКомпоненты разделены по контейнерам или серверам

Минимальная конфигурация

server {
    listen 80;
    server_name example.test;
    root /var/www/example/public;

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        internal;
    }

    location ~ \.php$ {
        return 404;
    }
}

try_files сначала ищет реальный файл, а затем направляет запрос в index.php. Директива fastcgi_pass задаёт адрес PHP-FPM, а SCRIPT_FILENAME сообщает, какой файл нужно выполнить.

internal не позволяет вызвать фронт-контроллер напрямую извне. Последний блок запрещает выполнение произвольных PHP-файлов. Вместе с корнем в каталоге public это заметно уменьшает доступную извне поверхность приложения.

Где искать ошибку

СимптомПервое место для проверки
404 для всех маршрутовtry_files, корень сайта и маршруты приложения
502 Bad GatewayРаботает ли PHP-FPM и совпадает ли путь к сокету
500 Internal Server ErrorЖурнал приложения и журнал ошибок PHP-FPM
CSS или изображения не найденыНаличие файла в public и права доступа

Полезно идти по цепочке запроса, а не менять конфигурацию наугад: сначала Nginx, затем соединение с PHP-FPM, потом само приложение.

Официальные источники

Документация Nginx: FastCGI module
Руководство PHP: FastCGI Process Manager

Следующая статья: структура PHP-проекта →