Сбой доступа к Unix-сокету PHP-FPM: практическое руководство
Ошибка подключения к сокету PHP-FPM (например, connect() to unix:/var/run/php/php7.4-fpm.sock failed) обычно возникает при взаимодействии веб-сервера (Nginx, Apache) с PHP-FPM. Причины могут быть разными: служба PHP-FPM не запущена, неверный путь к сокету, недостаточные права доступа или блокировка со стороны SELinux. Ниже рассмотрены основные способы диагностики и устранения.
Основное решение
Цель: восстановить работоспособность соединения через Unix-сокет.
Случай использования: ошибка появляется сразу после установки или перезапуска сервера, сокет существует, но не доступен.
- Проверить, запущен ли PHP-FPM:
- Убедиться, что сокет создан:
- Проверить права на сокет:
- Перезагрузить службы:
systemctl status php7.4-fpmPhp fpm sock failed (ошибка подключения к сокету php-fpm)
Если служба неактивна, запустить её:
systemctl start php7.4-fpm
ls -la /var/run/php/php7.4-fpm.sock
Если файл отсутствует, проверить конфигурацию пула (см. вариант 1).
stat -c '%a %U:%G' /var/run/php/php7.4-fpm.sock
Владельцем должен быть пользователь веб-сервера (www-data, nginx) или группа. Если нет, изменить права (вариант 2).
systemctl restart php7.4-fpm nginx
Типичные проблемы:
- Ошибка "Connection refused" – служба не слушает сокет. Проверить, что в конфигурации пула указан правильный
listen. - Ошибка "Permission denied" – неверный владелец или режим доступа. Исправить через
chownиchmod. - Сокет существует, но Nginx не может подключиться – несовпадение пути в
fastcgi_passв конфигурации Nginx.
Варианты решения
Как настроить права доступа к сокету PHP-FPM для веб-сервера?
Цель: разрешить веб-серверу (например, www-data) читать и записывать в сокет.
Случай использования: после изменения пользователя, от которого запущен Nginx, или при использовании нескольких пулов.
; Файл /etc/php/7.4/fpm/pool.d/www.conf
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
После изменений перезапустить PHP-FPM:
systemctl restart php7.4-fpm
Можно также изменить владельца существующего сокета вручную, но настройка в пуле гарантирует корректные права после каждого перезапуска.
Ошибка: если указанный пользователь не существует, служба не запустится. Проверить имя пользователя командой id www-data.
Что делать, если PHP-FPM не создает сокет в ожидаемом месте?
Цель: найти и исправить путь, по которому создается сокет.
Случай использования: после обновления конфигурации или переноса сервера.
Проверить директиву listen в пуле:
grep -E '^listen' /etc/php/*/fpm/pool.d/www.conf
Типичная запись: listen = /var/run/php/php7.4-fpm.sock. Если путь изменён, его необходимо согласовать с конфигурацией веб-сервера. Например, в Nginx указать fastcgi_pass unix:/новый/путь/php.sock;.
Также убедиться, что директория для сокета существует и доступна для записи PHP-FPM:
mkdir -p /var/run/php
chown root:root /var/run/php
chmod 755 /var/run/php
Ошибка: если директория не существует, сокет не создастся. В логах PHP-FPM будет сообщение cannot bind socket. Проверить логи: tail -f /var/log/php7.4-fpm.log.
Как заменить Unix-сокет на TCP-порт для подключения?
Цель: использовать TCP-соединение (например, при распределённой архитектуре).
Случай использования: PHP-FPM и веб-сервер работают на разных хостах или при проблемах с сокетами.
В конфигурации пула изменить listen:
; /etc/php/7.4/fpm/pool.d/www.conf
listen = 127.0.0.1:9000
; или listen = 9000 для всех интерфейсов
В Nginx соответственно изменить fastcgi_pass:
fastcgi_pass 127.0.0.1:9000;
Перезапустить обе службы:
systemctl restart php7.4-fpm nginx
Ошибка: порт может быть занят. Проверить netstat -tlnp | grep 9000. Также SELinux может блокировать соединение (вариант 4).
Как проверить, не блокирует ли SELinux доступ к сокету PHP-FPM?
Цель: убедиться, что политики SELinux или AppArmor не препятствуют подключению.
Случай использования: система с включённым SELinux (CentOS, Fedora).
Проверить статус SELinux:
getenforce
Если Enforcing, временно переключить в Permissive для теста:
setenforce 0
Если ошибка исчезает, настроить контекст или создать правило. Для PHP-FPM необходимо разрешить httpd подключение к сокету:
setsebool -P httpd_can_network_connect 1 # для TCP
setsebool -P httpd_can_network_connect_db 1 # если используется TCP для БД
Для Unix-сокета обычно достаточно стандартных политик, но если нет, изменить контекст:
semanage fcontext -a -t httpd_var_run_t '/var/run/php(/.*)?'
restorecon -Rv /var/run/php
Ошибка: SELinux может генерировать записи в audit.log. Просмотреть: ausearch -m avc -ts recent.
Как исправить ошибки подключения после обновления версии PHP?
Цель: восстановить связь после установки новой версии PHP.
Случай использования: обновление пакетов, при котором изменился путь к сокету или имя службы.
Проверить, какие версии установлены:
php -v
ls /etc/php/
Если появилась новая версия (например, 8.1), то служба называется php8.1-fpm, а сокет может располагаться в /var/run/php/php8.1-fpm.sock. Обновить конфигурацию Nginx, указав новый путь. Также скопировать или перенастроить пользовательские пулы.
Пример обновления конфигурации Nginx:
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
Перезапустить сервисы:
systemctl restart php8.1-fpm nginx
Ошибка: старая служба может остаться запущенной и конфликтовать. Остановить её: systemctl stop php7.4-fpm. Также удалить старый сокет, если он мешает.
Расширенные примеры и команды
1. Детальная проверка состояния службы PHP-FPM
systemctl status php7.4-fpm --no-pager
Вывод покажет, активна ли служба, PID, и последние логи. Пример результата:
● php7.4-fpm.service - The PHP 7.4 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php7.4-fpm.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2025-01-17 10:23:45 UTC; 2h 15min ago
Main PID: 12345 (php-fpm7.4)
Status: "Processes active: 0, idle: 2, Requests: 10, slow: 0, Traffic: 0req/sec"
CGroup: /system.slice/php7.4-fpm.service
├─12345 php-fpm: master process (/etc/php/7.4/fpm/php-fpm.conf)
├─12346 php-fpm: pool www
└─12347 php-fpm: pool www
2. Мониторинг логов PHP-FPM в реальном времени
tail -f /var/log/php7.4-fpm.log
Если ошибка возникает при попытке подключения, в логах появится запись типа:
[17-Jan-2025 12:34:56] ERROR: unable to bind listening socket for address '/var/run/php/php7.4-fpm.sock': Permission denied
3. Команда для массового изменения владельца сокетов во всех пулах
for pool in /etc/php/*/fpm/pool.d/*.conf; do
sed -i 's/^listen.owner.*/listen.owner = nginx/' "$pool"
sed -i 's/^listen.group.*/listen.group = nginx/' "$pool"
sed -i 's/^listen.mode.*/listen.mode = 0660/' "$pool"
done
После выполнения скрипта перезапустить PHP-FPM.
4. Генерация и тестирование подключения к TCP-порту с помощью curl
curl -v --unix-socket /var/run/php/php7.4-fpm.sock http://localhost/status 2>&1 | grep -i 'connected'
Если сокет рабочий, появится сообщение об успешном соединении. Для TCP-порта:
echo -e "GET /status HTTP/1.1\r\nHost: localhost\r\n\r\n" | timeout 2 nc 127.0.0.1 9000
Результат – ответ от PHP-FPM (например, статус пула).
5. Создание символической ссылки на сокет при его перемещении
Если сокет находится в нестандартном месте, а менять конфигурацию Nginx нежелательно, можно создать символическую ссылку:
ln -s /custom/path/php.sock /var/run/php/php7.4-fpm.sock
Важно: ссылка должна создаваться после запуска PHP-FPM, иначе она будет указывать на несуществующий файл. Автоматизировать через systemd:
# /etc/systemd/system/php-fpm-sock-link.service
[Unit]
Description=Create symlink for PHP-FPM socket
After=php7.4-fpm.service
Requires=php7.4-fpm.service
[Service]
Type=oneshot
ExecStart=/bin/ln -sf /custom/path/php.sock /var/run/php/php7.4-fpm.sock
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
6. Проверка совместимости версий PHP и конфигурации пула
Команда выявит синтаксические ошибки в конфигурации пула:
php-fpm7.4 -t
Пример успешного вывода:
[17-Jan-2025 14:00:00] NOTICE: configuration file /etc/php/7.4/fpm/php-fpm.conf test is successful
Если есть ошибка, она будет описана с указанием строки.