Передача PHP-запроса от Nginx к пулу PHP-FPM через FastCGI socket
DevOps

Как подключить PHP-FPM к Nginx через FastCGI

Настраиваем связку Nginx и PHP-FPM: находим socket, передаём SCRIPT_FILENAME, запрещаем выполнение чужих файлов и разбираем 404 и 502.

Содержание

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

Для рабочей связки нужно найти настоящий адрес этого сокета, дать Nginx право подключаться к нему и передать PHP-FPM точный путь к скрипту. Начнём с действующей службы, потому что копирование имени сокета с чужого сервера часто заканчивается 502.

Определите активную службу и socket

Имена зависят от дистрибутива и версии. Не копируйте /run/php/php8.x-fpm.sock без проверки:

systemctl list-units --type=service | grep -E 'php.*fpm'
systemctl status php-fpm --no-pager
sudo grep -R '^listen\s*=' /etc/php* /etc/php-fpm* 2>/dev/null
sudo ss -xlpn | grep php

В вашей системе служба может называться иначе. Сверьте pool, который обслуживает сайт, пользователя процесса, listen.owner, listen.group и listen.mode. Nginx должен иметь право подключаться, но делать socket доступным всем пользователям не нужно.

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

В следующем примере публичные файлы находятся в /var/www/example/public, а PHP-FPM принимает запросы через /run/php/php-fpm.sock. Блок подходит сайту с front controller index.php, если это предусмотрено его документацией:

server {
    listen 443 ssl;
    server_name example.com;
    root /var/www/example/public;
    index index.php index.html;

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

    location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php/php-fpm.sock;
    }
}

Замените socket и root фактическими значениями. try_files в PHP-location запрещает отправлять несуществующий путь интерпретатору. SCRIPT_FILENAME формирует абсолютный путь. Файл fastcgi_params и содержимое пакетных snippets различаются, поэтому проверьте, не задаётся ли параметр уже и что именно подключается.

Правило location / показано для приложения с front controller. Статический сайт или другой фреймворк требует иного fallback. Не направляйте неизвестные пути в index.php, если приложение этого не ожидает.

Ограничьте область выполнения

Каталог пользовательских загрузок не должен исполнять PHP. Если uploads находится внутри document root, добавьте более приоритетный запрет, соответствующий его точному пути:

location ^~ /uploads/ {
    try_files $uri =404;
}

Ещё лучше хранить загружаемые файлы вне каталога кода и отдавать их по отдельной проверенной схеме. Не используйте широкие regex, если не понимаете порядок выбора location; сначала изучите root, alias и try_files.

Ограничьте доступ к скрытым и служебным файлам отдельно. Конкретный список зависит от приложения: универсальный запрет может случайно скрыть ACME challenge или нужный ресурс.

Unix socket или TCP

Unix socket удобен, когда Nginx и FPM находятся на одном узле. TCP нужен между контейнерами или хостами, но адрес нельзя без необходимости слушать на публичном интерфейсе:

fastcgi_pass 127.0.0.1:9000;

Факт открытого порта проверьте ss -ltnp. Для удалённого FPM потребуется отдельная защищённая сеть и модель доверия; FastCGI не следует публиковать в интернет.

Проверка

sudo nginx -t
sudo systemctl reload nginx
systemctl is-active php-fpm
curl -I https://example.com/

Имя службы подставьте реальное. Для теста можно временно создать простой PHP-файл, возвращающий фиксированный текст, но не phpinfo() на публичном сайте: он раскрывает конфигурацию и окружение. Удалите тест сразу после проверки.

Одновременно наблюдайте журналы:

sudo journalctl -u nginx -u php-fpm --since "10 minutes ago"
sudo tail -n 50 /var/log/nginx/error.log

Разбор ошибок

502 Bad Gateway

Сначала проверьте активность FPM, фактический socket/порт и права. Сообщение No such file or directory обычно указывает на неверный путь или остановленную службу; Permission denied — на владельца, группу или контекст безопасности. Не исправляйте последнее chmod 777.

File not found или Primary script unknown

Сравните root, запрошенный URI, SCRIPT_FILENAME и путь внутри контейнера. Nginx и FPM могут видеть разные файловые системы. Логируйте точные пути только в защищённый журнал и не показывайте их посетителю.

PHP скачивается или виден как текст

Запрос не попал в FastCGI-location либо конфигурация не активна. Это критично: временно уберите сайт из доступа, исправьте выбор виртуального хоста и проверьте, что исходный код и секреты не были выданы.

404 на front controller

Проверьте существование index.php, root и fallback. Не убирайте try_files вслепую: оно может предотвращать выполнение несуществующих или загруженных путей.

Откат

Держите предыдущий конфиг рядом вне публичного каталога. При ошибке верните его, выполните nginx -t и reload. Изменения pool PHP-FPM откатывайте отдельно и проверяйте синтаксис средствами установленной версии PHP. Общая схема reverse proxy описана в руководстве по проксированию.

Эксплуатационный минимум

После запуска контролируйте очередь и предел workers FPM, время PHP-запросов и память процессов. Когда пул исчерпан, увеличение timeout Nginx лишь удлиняет очередь. Настройте slow log и status FPM только по документации установленной версии, ограничьте их локальной сетью и не публикуйте диагностические страницы.

Обновление PHP выполняйте как отдельный релиз: новый socket часто получает другое имя. Сначала поднимите новый pool, проверьте совместимость приложения, переключите Nginx и сохраните возможность вернуть прежний upstream.

Первоисточники

Рекламное местоВаша компания здесьРазместить рекламу

Самопроверка

Проверьте, что материал усвоен

Ответьте на все вопросы. Результат сохранится только в этом браузере и будет учтён в статистике прочитанных материалов.

01Где узнать фактический socket PHP-FPM?
02Какой параметр сообщает PHP-FPM путь выполняемого скрипта?
03Что делать перед reload Nginx?

Разбираем коротко

Частые вопросы

Почему Nginx возвращает 502 Bad Gateway при работе с PHP-FPM?

Обычно Nginx не может подключиться к указанному socket или TCP-порту: служба остановлена, путь не совпадает с версией пула либо права socket не позволяют подключение. Проверяйте оба журнала и фактический listen.

Зачем ставить try_files $uri =404 перед fastcgi_pass?

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

Можно ли направить все запросы сайта прямо в PHP-FPM?

Front controller допустим для фреймворка, но правило должно соответствовать его документации. Статические файлы обычно отдаёт Nginx, а выполнение PHP ограничивается ожидаемой точкой входа и реальными файлами.