Найти в Дзене

Nginx + PHP-FPM: как работает связка и решаем ошибки 502 и 504

Nginx + PHP-FPM: как работает связка и почему возникают ошибки 502 и 504 > Часть 3 серии про Nginx > В прошлой части мы разобрали virtual hosts и структуру сайтов. > Теперь переходим к главному: как Nginx выполняет PHP-код и что такое PHP-FPM на самом деле. --- Введение Nginx + PHP-FPM — это стандартная связка для обработки PHP-приложений в продакшене. Понимание принципов её работы критически важно для диагностики и решения проблем. В этой статье разберём: --- Главная мысль, которую нужно понять сразу 👉 Nginx НЕ исполняет PHP. Вообще. Никогда. Nginx — это веб-сервер, который: Если PHP-FPM не отвечает или работает некорректно — проблема не в Nginx, а в конфигурации или состоянии PHP-FPM. --- Что такое PHP-FPM простыми словами PHP-FPM (FastCGI Process Manager) — это менеджер процессов PHP, который: Схема взаимодействия выглядит так: ```text Браузер ↓ HTTP-запрос Nginx ↓ FastCGI-протокол PHP-FPM ↓ выполнение кода PHP-процесс ↓ результат PHP-FPM → Nginx → Браузер ``` --- Как Nginx определ

Nginx + PHP-FPM: как работает связка и решаем ошибки 502 и 504

Nginx + PHP-FPM: как работает связка и почему возникают ошибки 502 и 504

> Часть 3 серии про Nginx

> В прошлой части мы разобрали virtual hosts и структуру сайтов.

> Теперь переходим к главному: как Nginx выполняет PHP-код и что такое PHP-FPM на самом деле.

---

Введение

Nginx + PHP-FPM — это стандартная связка для обработки PHP-приложений в продакшене. Понимание принципов её работы критически важно для диагностики и решения проблем.

В этой статье разберём:

  • архитектуру взаимодействия Nginx и PHP-FPM;
  • типичные ошибки 502 и 504 и их причины;
  • практические методы диагностики;
  • настройку таймаутов и пулов процессов;
  • полные примеры конфигураций для реальных проектов.

---

Главная мысль, которую нужно понять сразу

👉 Nginx НЕ исполняет PHP. Вообще. Никогда.

Nginx — это веб-сервер, который:

  • принимает HTTP-запросы;
  • анализирует URL и заголовки;
  • передаёт PHP-файлы в PHP-FPM через протокол FastCGI;
  • ждёт результат выполнения;
  • отдаёт ответ клиенту.

Если PHP-FPM не отвечает или работает некорректно — проблема не в Nginx, а в конфигурации или состоянии PHP-FPM.

---

Что такое PHP-FPM простыми словами

PHP-FPM (FastCGI Process Manager) — это менеджер процессов PHP, который:

  • запускает и управляет PHP-процессами;
  • поддерживает пул воркеров для параллельной обработки запросов;
  • принимает запросы от Nginx через протокол FastCGI;
  • выполняет PHP-код из .php файлов;
  • возвращает результат выполнения (HTML, JSON и т.д.) обратно в Nginx.

Схема взаимодействия выглядит так:

```text

Браузер

↓ HTTP-запрос

Nginx

↓ FastCGI-протокол

PHP-FPM

↓ выполнение кода

PHP-процесс

↓ результат

PHP-FPM → Nginx → Браузер

```

---

Как Nginx определяет, что файл — PHP

Nginx использует директиву location с регулярным выражением для определения PHP-файлов:

```nginx

location ~ \.php$ {

конфигурация обработки PHP

}

```

Это означает:

  • любой запрос, URL которого заканчивается на .php;
  • будет обработан этим блоком location;
  • и передан в PHP-FPM для выполнения.

---

Базовая конфигурация Nginx для PHP

Минимально рабочая конфигурация для обработки PHP:

```nginx

location ~ \.php$ {

include fastcgi_params;

fastcgi_pass unix:/run/php/php8.2-fpm.sock;

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

}

```

Разберём каждую директиву:

  • include fastcgi_params; — подключает стандартные параметры FastCGI;
  • fastcgi_pass — указывает, куда передавать запрос (сокет или TCP);
  • fastcgi_index — индексный файл по умолчанию;
  • fastcgi_param SCRIPT_FILENAME — самая важная строка, указывает PHP-FPM путь к файлу для выполнения.

---

fastcgi_pass — способы подключения к PHP-FPM

Есть два варианта подключения Nginx к PHP-FPM.

Вариант 1. Unix-сокет (рекомендуется)

```nginx

fastcgi_pass unix:/run/php/php8.2-fpm.sock;

```

Преимущества:

  • быстрее (нет сетевых задержек);
  • безопаснее (нет сетевого доступа);
  • стандартный способ для одного сервера;
  • меньше накладных расходов.

Недостатки:

  • работает только локально на том же сервере.

Вариант 2. TCP-подключение

```nginx

fastcgi_pass 127.0.0.1:9000;

```

Используется, если:

  • PHP-FPM запущен в Docker-контейнере;
  • PHP-FPM находится на другом сервере;
  • нужна сетевая изоляция между процессами.

---

Где узнать путь к сокету PHP-FPM

Путь к сокету указывается в конфигурационном файле пула PHP-FPM.

Ubuntu / Debian

```bash

/etc/php/8.2/fpm/pool.d/www.conf

```

Ищите строку:

```ini

listen = /run/php/php8.2-fpm.sock

```

CentOS / Rocky Linux

```bash

/etc/php-fpm.d/www.conf

```

👉 Этот путь должен точно совпадать с fastcgi_pass в конфигурации Nginx.

---

SCRIPT_FILENAME — самая важная строка

```nginx

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

```

Если эта строка неправильная или отсутствует → 502 Bad Gateway гарантирован.

Что здесь происходит:

  • $document_root — значение директивы root из блока server;
  • $fastcgi_script_name — путь к PHP-файлу из URL запроса;
  • результат — полный абсолютный путь к файлу на диске.

Пример:

```text

URL запроса: /index.php

root: /var/www/site/public

Итоговый SCRIPT_FILENAME:

/var/www/site/public/index.php

```

PHP-FPM использует этот путь для загрузки и выполнения файла.

---

index.php и try_files — правильная связка

Для современных PHP-фреймворков (Laravel, Symfony, Bitrix, WordPress) критически важно правильно настроить try_files:

```nginx

location / {

try_files $uri $uri/ /index.php?$query_string;

}

```

Что это даёт:

  • если файл существует — отдаём его напрямую;
  • если это директория — пробуем найти индексный файл;
  • если ничего не найдено — передаём запрос в index.php с сохранением query string;
  • идеально для фреймворков с роутингом через index.php.

---

Полный пример server block для PHP-проекта

Продакшен-адекватная конфигурация для PHP-приложения:

```nginx

server {

listen 80;

server_name site.ru www.site.ru;

root /var/www/site.ru/public;

index index.php index.html;

access_log /var/www/site.ru/logs/access.log;

error_log /var/www/site.ru/logs/error.log;

location / {

try_files $uri $uri/ /index.php?$query_string;

}

location ~ \.php$ {

include fastcgi_params;

fastcgi_pass unix:/run/php/php8.2-fpm.sock;

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Таймауты (подробнее ниже)

fastcgi_read_timeout 60s;

fastcgi_connect_timeout 60s;

}

Защита скрытых файлов

location ~ /\. {

deny all;

access_log off;

log_not_found off;

}

}

```

👉 Это здоровый, продакшен-адекватный минимум для большинства PHP-проектов.

---

Готовые конфигурации для популярных фреймворков

Для конкретных фреймворков и CMS могут потребоваться дополнительные настройки. Ниже приведены ссылки на готовые конфигурации, основанные на официальной документации:

  • Nginx для Bitrix CMS — конфигурация с поддержкой URL rewriting через /bitrix/urlrewrite.php, защитой директорий и увеличенными таймаутами для операций Bitrix.
  • Nginx для WordPress — конфигурация с поддержкой pretty permalinks, защитой директории uploads и оптимизацией для WordPress.
  • Nginx для Laravel — конфигурация с правильной настройкой root на директорию public, обработкой только index.php и поддержкой Laravel роутинга.
  • Nginx для Astro (статический сайт) — конфигурация для статических Astro сайтов с поддержкой SPA роутинга, кеширования и gzip сжатия.

Все конфигурации проверены и основаны на официальной документации соответствующих проектов.

---

Ошибка 502 Bad Gateway — причины и диагностика

Что означает 502

Nginx не смог получить ответ от PHP-FPM или получил некорректный ответ.

Частые причины

  1. PHP-FPM не запущен — самая частая причина;
  2. Неверный путь к сокету — сокет не существует или путь указан неправильно;
  3. PHP упал с fatal error — критическая ошибка в PHP-коде;
  4. Недостаточно памяти — сервер исчерпал доступную память;
  5. Неверный SCRIPT_FILENAME — PHP-FPM не может найти файл для выполнения;
  6. Проблемы с правами доступа — Nginx не может прочитать сокет или файлы.

Диагностика по шагам

Шаг 1. Проверка статуса PHP-FPM:

```bash

systemctl status php8.2-fpm

```

Если сервис не запущен:

```bash

systemctl start php8.2-fpm

systemctl enable php8.2-fpm

```

Шаг 2. Проверка существования сокета:

```bash

ls -l /run/php/

```

Должен быть файл php8.2-fpm.sock (или другой, в зависимости от версии).

Шаг 3. Проверка логов PHP-FPM:

```bash

tail -f /var/log/php8.2-fpm.log

```

Или для конкретного пула:

```bash

tail -f /var/log/php8.2-fpm/www-error.log

```

Шаг 4. Проверка логов Nginx:

```bash

tail -f /var/www/site.ru/logs/error.log

```

Или системный лог:

```bash

tail -f /var/log/nginx/error.log

```

Шаг 5. Проверка конфигурации:

```bash

nginx -t

php-fpm8.2 -t

```

👉 Начинайте всегда с логов, не с конфигов. Логи покажут реальную причину проблемы.

---

Ошибка 504 Gateway Timeout — причины и решения

Что означает 504

PHP слишком долго выполняет запрос, Nginx устал ждать и закрыл соединение.

Типовые причины

  • Тяжёлые запросы к базе данных — медленные SQL-запросы без индексов;
  • Внешние API без таймаутов — зависание на запросах к внешним сервисам;
  • Зависший PHP-процесс — бесконечный цикл или блокирующая операция;
  • Маленькие лимиты пула FPM — все процессы заняты, новые запросы ждут;
  • Неправильные настройки таймаутов — несоответствие между Nginx, PHP-FPM и PHP.

---

Настройка таймаутов на всех уровнях

Таймауты нужно настраивать на трёх уровнях, и они должны быть согласованы.

В Nginx

```nginx

location ~ \.php$ {

include fastcgi_params;

fastcgi_pass unix:/run/php/php8.2-fpm.sock;

Время ожидания ответа от PHP-FPM

fastcgi_read_timeout 60s;

Время на установку соединения с PHP-FPM

fastcgi_connect_timeout 60s;

Время на отправку запроса в PHP-FPM

fastcgi_send_timeout 60s;

}

```

В PHP-FPM (pool.d/www.conf)

```ini

; Максимальное время выполнения запроса (в секундах)

; 0 = без ограничений (не рекомендуется)

request_terminate_timeout = 60

```

В PHP (php.ini)

```ini

; Максимальное время выполнения скрипта (в секундах)

max_execution_time = 60

; Максимальное время загрузки файла

max_input_time = 60

```

👉 Все три уровня должны быть согласованы. Рекомендуется устанавливать одинаковые значения или делать таймаут PHP-FPM немного больше, чем PHP.

Пример согласованной настройки:

```text

Nginx fastcgi_read_timeout: 60s

PHP-FPM request_terminate_timeout: 65s

PHP max_execution_time: 60s

```

Это даёт небольшой запас для завершения процесса после таймаута PHP.

---

Настройка пула PHP-FPM

Каждый pool — это отдельный набор PHP-процессов с собственными настройками. Правильная настройка пула критически важна для производительности.

Базовые параметры пула

```ini

; Режим управления процессами: static, dynamic, ondemand

pm = dynamic

; Максимальное количество дочерних процессов

pm.max_children = 50

; Количество процессов, запускаемых при старте

pm.start_servers = 10

; Минимальное количество свободных процессов

pm.min_spare_servers = 5

; Максимальное количество свободных процессов

pm.max_spare_servers = 15

; Количество запросов, после которого процесс перезапускается

pm.max_requests = 500

```

Что это значит

  • pm.max_children — максимум одновременных запросов. Если все процессы заняты → новые запросы ждут → возможен 504;
  • pm.start_servers — сколько процессов запускается при старте PHP-FPM;
  • pm.min_spare_servers — минимальное количество процессов в режиме ожидания;
  • pm.max_spare_servers — максимальное количество процессов в режиме ожидания;
  • pm.max_requests — после этого количества запросов процесс перезапускается (защита от утечек памяти).

Расчёт оптимального количества процессов

Формула для pm.max_children:

```text

max_children = (RAM доступная для PHP) / (RAM на один PHP-процесс)

```

Пример:

```text

Доступно RAM: 2 GB

Один PHP-процесс: ~50 MB

max_children = 2048 MB / 50 MB ≈ 40 процессов

```

Режимы управления процессами

pm = static — фиксированное количество процессов:

```ini

pm = static

pm.max_children = 20

```

Подходит для стабильной нагрузки, предсказуемое потребление памяти.

pm = dynamic — динамическое управление (рекомендуется):

```ini

pm = dynamic

pm.max_children = 50

pm.start_servers = 10

pm.min_spare_servers = 5

pm.max_spare_servers = 15

```

Подходит для переменной нагрузки, оптимальное использование ресурсов.

pm = ondemand — процессы запускаются по требованию:

```ini

pm = ondemand

pm.max_children = 50

pm.process_idle_timeout = 10s

```

Подходит для серверов с низкой нагрузкой, экономия ресурсов.

---

Типовые ошибки новичков

Путают Apache mod_php и PHP-FPM — думают, что PHP встроен в Nginx, как в Apache.

Думают, что PHP — часть Nginx — не понимают архитектуру FastCGI.

Правят php.ini, а проблема в FPM — не различают настройки PHP и PHP-FPM.

Игнорируют логи — начинают менять конфиги наугад вместо чтения логов.

Сразу крутят таймауты — увеличивают таймауты, не понимая реальную причину медленной работы.

Неправильный порядок location — блок location ~ \.php$ должен быть после location /.

Забывают про try_files — без него фреймворки с роутингом не работают.

---

Чек-лист диагностики проблем с PHP

Если PHP не работает, проверьте по порядку:

  • [ ] PHP-FPM запущен — systemctl status php8.2-fpm
  • [ ] Путь к сокету совпадает — проверьте fastcgi_pass в Nginx и listen в pool.conf
  • [ ] SCRIPT_FILENAME корректный — должен содержать полный путь к файлу
  • [ ] try_files настроен — для фреймворков обязателен
  • [ ] Логи читаются — начните с tail -f на error.log
  • [ ] Нет fatal error — проверьте логи PHP-FPM
  • [ ] Права доступа корректны — Nginx должен читать файлы и сокет
  • [ ] Конфигурация синтаксически правильна — nginx -t и php-fpm8.2 -t
  • [ ] Достаточно памяти — проверьте free -h и логи OOM killer
  • [ ] Таймауты согласованы — проверьте на всех трёх уровнях

---

Рекомендации по настройке и безопасности

Производительность

  • Используйте Unix-сокеты вместо TCP для локальных подключений.
  • Настройте кэширование статических файлов в Nginx.
  • Используйте OPcache для PHP (включён по умолчанию в современных версиях).
  • Мониторьте использование памяти и CPU процессами PHP-FPM.

Безопасность

  • Ограничьте выполнение PHP только в нужных директориях.
  • Используйте отдельные пулы для разных сайтов с разными правами.
  • Настройте open_basedir в PHP для ограничения доступа к файлам.
  • Регулярно обновляйте PHP и PHP-FPM до актуальных версий.

Мониторинг

  • Настройте ротацию логов для предотвращения переполнения диска.
  • Используйте мониторинг процессов PHP-FPM (например, через systemd или внешние системы).
  • Отслеживайте метрики: количество активных процессов, время выполнения запросов, ошибки.

---

Что будет в части 4

Дальше логичное продолжение:

Часть 4 — Reverse Proxy и проксирование (API, Node.js, Python)

  • proxy_pass и проксирование запросов;
  • работа с заголовками;
  • WebSocket через Nginx;
  • настройка backend-сервисов за Nginx.

---

Заключение

Связка Nginx + PHP-FPM — это не магия, а чёткий контракт между компонентами:

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

Когда вы понимаете эту архитектуру, 502 и 504 перестают пугать — они становятся понятными сигналами о конкретных проблемах, которые можно быстро диагностировать и исправить.

Правильная настройка таймаутов, пулов процессов и мониторинг логов — это основа стабильной работы PHP-приложений в продакшене.