Связка Nginx и PHP-FPM в Debian и Ubuntu обычно работает стабильно годами, но одна из самых частых поломок выглядит неприятно и не слишком информативно: в логах Nginx появляется connect() to unix failed (13: Permission denied), а сайт начинает отдавать 502 Bad Gateway. На практике это почти всегда не «сломанный PHP», а проблема доступа к Unix socket.
Сценарий типичный: обновили пакет, поменяли пул PHP-FPM, отредактировали www.conf, перенесли конфиг с другого сервера, переключили версию PHP или просто не совпали пользователь и группа. В итоге Nginx пытается подключиться к сокету, но ядро запрещает доступ.
Хорошая новость в том, что диагностируется такая ситуация довольно быстро. Главное — не начинать с хаотичных изменений прав на всё подряд вроде chmod 777. Это не исправление, а способ замаскировать реальную проблему и создать новую.
Ниже разберём, как устроено взаимодействие Nginx и PHP-FPM через Unix socket, какие параметры отвечают за доступ, как проверить пользователя веб-сервера, что смотреть в php-fpm www.conf и почему проблема иногда кроется не в самом сокете, а в каталоге, где он лежит.
Материал ориентирован на Debian и Ubuntu, но сама логика пригодится и на других дистрибутивах. Примеры ниже даны для типовой схемы с php8.2-fpm или php8.3-fpm, однако подход одинаков и для других версий.
Как выглядит ошибка и что она означает
Обычно в логе Nginx можно увидеть одну из таких строк:
connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied) while connecting to upstream
connect() to unix:/var/run/php/php-fpm.sock failed (13: Permission denied) while connecting to upstream
Ключевой фрагмент здесь — Permission denied. Он означает, что сокет существует или путь к нему указан корректно, но процесс Nginx не может открыть его из-за ограничений на уровне файловых прав.
Если бы сокета не было вообще, ошибка чаще выглядела бы как No such file or directory. А если PHP-FPM не слушал бы нужный адрес, вы бы увидели другой набор симптомов. Поэтому сообщение connect() to unix failed с кодом 13 почти всегда указывает именно на проблему прав доступа.
Самая частая причина: Nginx работает от пользователя
www-data, а сокет PHP-FPM создан с владельцем или группой, которые этому пользователю недоступны.
Почему Unix socket ломается чаще, чем кажется
Unix socket — это специальный файл в файловой системе, через который Nginx общается с PHP-FPM локально на сервере. В Debian и Ubuntu он обычно создаётся в /run/php/ и выглядит как php8.2-fpm.sock.
Для подключения к сокету должны сойтись сразу несколько условий:
- Nginx должен указывать на правильный путь в
fastcgi_pass. - Сам сокет должен существовать.
- Права на сокет должны позволять подключение.
- Права на каталог, где лежит сокет, тоже должны позволять доступ.
- PHP-FPM должен запускать пул с корректными настройками
listen.owner,listen.groupиlisten.mode.
Достаточно одной ошибки в этой цепочке — и вы получите классический nginx permission denied.
Если проект размещён на виртуальном хостинге, доступ к системным пулам и сокетам обычно ограничен, и такие ошибки чаще актуальны для выделенных окружений. На своих серверах и в VDS эту схему нужно контролировать самостоятельно.
С чего начинать диагностику
Первое правило: сначала смотрим логи и фактическое состояние системы, потом меняем конфиг. Иначе очень легко лечить не ту проблему.
1. Проверяем лог Nginx
sudo tail -n 50 /var/log/nginx/error.log
Если у вас отдельный лог для виртуального хоста, смотрите и его. Нужно подтвердить, что ошибка действительно связана с connect() to unix failed и именно с Permission denied.
2. Проверяем, запущен ли PHP-FPM
sudo systemctl status php8.2-fpm
sudo systemctl status php8.3-fpm
Подставьте свою версию PHP. Если служба неактивна, сокет может не создаваться вовсе. Но даже при активной службе права на сокет могут быть неверными.
3. Смотрим, существует ли socket и какие у него права
ls -l /run/php/
stat /run/php/php8.2-fpm.sock
Вас интересуют владелец, группа и режим доступа. Для типовой установки в Debian и Ubuntu часто ожидается что-то вроде владельца www-data и режима 660.
4. Проверяем права на каталог
namei -l /run/php/php8.2-fpm.sock
Это очень полезная команда, о которой часто забывают. Даже если права на сам php-fpm socket выглядят нормальными, один из каталогов по пути может запрещать доступ. Например, сокет лежит в кастомном каталоге, у которого нет права на выполнение для нужной группы.
5. Проверяем, от какого пользователя работает Nginx
ps -o user,group,cmd -C nginx
grep -R "^user" /etc/nginx/nginx.conf
На Debian и Ubuntu это почти всегда www-data, но на нестандартных сборках или после ручных правок может быть иначе.
Если вы ведёте несколько сайтов на одном сервере, полезно заранее зафиксировать схему пользователей, групп и пулов PHP-FPM, чтобы не разбирать такие инциденты в аварийном режиме.
Какие параметры PHP-FPM отвечают за доступ к сокету
Главные настройки находятся в конфиге пула, обычно это файл вида /etc/php/8.2/fpm/pool.d/www.conf. Если у вас несколько пулов, проблема может быть не в www.conf, а в конкретном файле сайта.
Ищем такие параметры:
listen = /run/php/php8.2-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
Разберём их по смыслу:
listen— путь к Unix socket.listen.owner— владелец сокета.listen.group— группа сокета.listen.mode— права доступа к сокету.
Если Nginx работает от www-data, то безопасный и практичный вариант для большинства случаев — дать сокету владельца и группу www-data с режимом 0660.
После изменения конфигурации нужен перезапуск или reload PHP-FPM, чтобы сокет был создан заново с новыми параметрами.
sudo systemctl restart php8.2-fpm
sudo systemctl reload nginx
Если вы параллельно меняете и инфраструктуру сайта, полезно держать под рукой отдельный план миграции без простоя: перенос сайта с минимальным downtime. Это помогает не смешивать ошибки сокета с последствиями переезда.

Типовой рабочий вариант для Debian/Ubuntu
Если у вас обычный один сервер без экзотики, начните с такой схемы: Nginx работает от www-data, PHP-FPM пул тоже настроен на сокет в /run/php/, а права выставлены через listen.owner и listen.group.
Пример блока из www.conf:
[www]
user = www-data
group = www-data
listen = /run/php/php8.2-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
И соответствующий фрагмент в конфиге сайта Nginx:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
Важно, чтобы путь в fastcgi_pass совпадал с тем, что указан в listen. Банально, но именно из-за старого пути после апгрейда с php8.1-fpm на php8.2-fpm часто начинаются поиски «битых прав», хотя проблема в несовпадении имени сокета.
Что ломается чаще всего на практике
Неверная группа сокета
Очень частый случай: пул PHP-FPM настроен так, что сокет создаётся с группой, в которой нет пользователя Nginx. Например, владелец сайта — отдельный системный пользователь, а Nginx продолжает работать как www-data.
В таком случае есть два рабочих подхода: либо привести сокет к группе www-data, либо осознанно добавить Nginx в нужную группу. Второй вариант требует аккуратности и понимания модели доступа, особенно на сервере с несколькими сайтами.
Права на сокет слишком строгие
Если установлен режим 0600, подключиться к сокету сможет только владелец. Для Nginx это обычно недостаточно, если он не является тем же пользователем.
Нормальный компромисс для большинства установок — 0660. Делать 0666 обычно не нужно.
Сокет лежит в нестандартном каталоге
Иногда администратор переносит сокет в каталог проекта, например в /home/site/run/ или /srv/app/tmp/. Сам файл сокета может иметь правильные права, но один из родительских каталогов не даёт Nginx пройти по пути.
Именно поэтому команда namei -l так полезна: она показывает права на каждом уровне.
Смешение пользователей пула и файлов сайта
Многие пытаются решить всё одной моделью: и PHP-FPM, и файлы сайта, и сокет, и Nginx должны работать от одного пользователя. Иногда это удобно, но нередко приводит к путанице. Важно понимать: права на сокет — это отдельная история, не всегда напрямую связанная с владельцем файлов проекта.
Пошаговый план исправления
Если нужно восстановить работу быстро и без лишних экспериментов, идите по такому порядку.
- Убедитесь, что в логе Nginx действительно ошибка
Permission deniedпри доступе к Unix socket. - Проверьте, что PHP-FPM запущен и создаёт нужный сокет.
- Сверьте путь
fastcgi_passв Nginx с параметромlistenв пуле PHP-FPM. - Посмотрите владельца, группу и режим сокета.
- Проверьте доступ к каталогам по пути до сокета.
- Приведите
listen.owner,listen.groupиlisten.modeк ожидаемой схеме. - Перезапустите PHP-FPM, затем перечитайте конфиг Nginx.
- Проверьте логи повторно.
В большинстве случаев проблема решается уже на шагах 3–6.

Пример полной проверки на сервере
Допустим, у вас в логе такая ошибка:
connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied) while connecting to upstream
Тогда последовательность может быть такой:
sudo grep -R "fastcgi_pass" /etc/nginx/sites-enabled
sudo grep -R "^listen" /etc/php/8.2/fpm/pool.d/
ls -l /run/php/
namei -l /run/php/php8.2-fpm.sock
ps -o user,group,cmd -C nginx
sudo systemctl restart php8.2-fpm
sudo nginx -t
sudo systemctl reload nginx
После этого откройте сайт снова и параллельно смотрите лог:
sudo tail -f /var/log/nginx/error.log
Если ошибка не исчезла, почти всегда проблема в том, что вы исправили не тот пул, не ту версию PHP или не тот виртуальный хост.
Когда проблема не в сокете, а выглядит похоже
Есть несколько ситуаций, которые внешне напоминают ошибку прав на Unix socket, но корень проблемы другой.
Неправильный путь к сокету после обновления PHP
Например, PHP-FPM уже работает как php8.3-fpm, а Nginx всё ещё смотрит в /run/php/php8.2-fpm.sock. В этом случае ошибка чаще будет про отсутствие файла, но в сложных конфигурациях легко запутаться и начать править не там.
Несколько пулов PHP-FPM
Один сайт использует www.conf, другой — отдельный пул site.conf. Вы меняете глобальный конфиг, а реальный трафик идёт в другой сокет. В результате кажется, что listen.owner не работает, хотя вы просто редактировали не тот файл.
Systemd override или tmpfiles
Если каталог для сокета создаётся нестандартно, его права могут переопределяться при старте системы. Тогда после ручного исправления всё «вдруг снова ломается» после reboot.
Если сервером управляют через панель, полезно заранее проверить, не переписывает ли она параметры пулов и виртуальных хостов. В таких сценариях помогает отдельный обзор: сравнение панелей управления для VDS.
Почему не стоит лечить это через chmod 777
Такой совет до сих пор встречается в случайных обсуждениях, но использовать его в продакшене нельзя. Да, иногда это временно снимает симптом, потому что все получают доступ ко всему. Но вместе с этим вы теряете контроль над моделью безопасности и усложняете дальнейшую диагностику.
Если для починки
php-fpm socketпонадобился777, значит, причина не найдена, а просто скрыта.
Правильное решение — определить, какой пользователь должен подключаться к сокету, и явно выдать доступ через listen.owner, listen.group и listen.mode.
Что выбрать: Unix socket или TCP localhost
Иногда после нескольких неудачных попыток хочется отказаться от Unix socket и перевести связку на TCP, например 127.0.0.1:9000. Это рабочий вариант, но не универсальная «таблетка».
У TCP свои плюсы: проще визуально понимать схему, легче диагностировать сетевыми инструментами, нет файловых прав на сокет. Но появляются сетевые параметры, а также требуется следить, чтобы PHP-FPM слушал только локальный интерфейс.
Unix socket в локальной связке Nginx и PHP-FPM остаётся нормальным и эффективным выбором. Если всё настроено правильно, проблем он не создаёт. Поэтому сначала лучше исправить права, а не менять архитектуру без необходимости.
Мини-чеклист после исправления
- Путь в
fastcgi_passсовпадает сlisten. - Nginx работает от того пользователя, которому доступен сокет.
listen.ownerиlisten.groupсоответствуют вашей схеме.listen.modeобычно установлен в0660.- Каталог с сокетом доступен по всей цепочке пути.
- После изменения конфига PHP-FPM был перезапущен.
nginx -tвыполняется без ошибок.
Итог
Ошибка nginx permission denied при подключении к php-fpm socket в Debian и Ubuntu почти всегда сводится к трём вещам: неверный путь, неверный владелец или группа сокета, либо недостаточные права на сам сокет или каталог с ним. Это неприятная, но обычно быстрая в исправлении проблема.
Если действовать последовательно — проверить лог, состояние службы, путь сокета, пользователя Nginx, параметры listen.owner, listen.group и права на каталог — причина находится без долгих догадок. А главное, без опасных костылей вроде глобальных разрешений на запись и чтение.
На рабочих серверах лучше придерживаться простой и предсказуемой схемы: Nginx и PHP-FPM согласованы по пользователю и группе, сокеты лежат в стандартном каталоге, а каждый пул имеет явно заданные параметры доступа. Тогда даже после обновлений и миграций такие сбои диагностируются за несколько минут.


