502 Bad Gateway
Nginx получил неверный ответ от upstream-сервера (PHP-FPM, Node.js, proxy). Бэкенд недоступен, упал или возвращает некорректный HTTP-ответ. Чаще всего встречается в связке Nginx + PHP-FPM.
systemctl status php8.2-fpm
systemctl status php8.1-fpm
ps aux | grep php-fpm | grep -v grep
tail -50 /var/log/nginx/error.log | grep -i "502"
tail -50 /var/log/nginx/error.log | grep -i "upstream"
tail -50 /var/log/nginx/error.log | grep -i "connect()"
upstream closed prematurely — бэкенд упал во время обработки.
no live upstreams — все бэкенды в пуле нерабочие.
tail -50 /var/log/php8.2-fpm.log
journalctl -u php8.2-fpm --since "1 hour ago" --no-pager
grep "listen =" /etc/php/*/fpm/pool.d/www.conf
grep "fastcgi_pass" /etc/nginx/sites-enabled/*
ls -la /run/php/
grep "max_children" /etc/php/*/fpm/pool.d/www.conf
ps aux | grep php-fpm | grep -c pool
grep "max children reached" /var/log/php8.2-fpm.log | tail -5
systemctl restart php8.2-fpm
nginx -t
systemctl reload nginx
curl -sI https://example.com | head -1
Частые причины 502
- PHP-FPM остановлен или crashed
- Несовпадение сокета в Nginx и PHP-FPM (после обновления PHP)
- pm.max_children слишком мал — все worker'ы заняты
- Нехватка RAM — OOM Killer убил PHP-FPM
- PHP скрипт использует слишком много памяти и worker падает
- Firewall блокирует соединение между Nginx и бэкендом
504 Gateway Timeout
Nginx дождался ответа от бэкенда, но тот не уложился в отведённое время. Бэкенд работает, но слишком медленно. Типично для тяжёлых запросов: импорт, экспорт, сложные SQL-запросы, медленные API.
grep "timed out" /var/log/nginx/error.log | tail -10
grep "upstream timed out" /var/log/nginx/error.log | tail -10
mysqladmin -u root -p processlist
mysql -u root -p -e "SHOW FULL PROCESSLIST;"
# Добавить в server или location блок Nginx:
proxy_read_timeout 300s;
proxy_send_timeout 300s;
fastcgi_read_timeout 300s;
fastcgi_send_timeout 300s;
nginx -t
systemctl reload nginx
grep "max_execution_time" /etc/php/8.2/fpm/php.ini
grep "request_terminate_timeout" /etc/php/8.2/fpm/pool.d/www.conf
systemctl restart php8.2-fpm
uptime
top -bn1 | head -15
iostat -x 1 3
free -h
Частые причины 504
- Медленный SQL запрос без индексов
- Блокировка таблиц в MySQL (LOCK WAIT)
- Внешний API не отвечает (curl запрос из PHP)
- PHP request_terminate_timeout слишком мал
- Nginx proxy_read_timeout / fastcgi_read_timeout слишком мал
- Сервер перегружен (CPU/disk I/O)
500 Internal Server Error
Сервер столкнулся с непредвиденной ошибкой. Это «универсальная» ошибка — причина может быть в коде PHP, конфигурации Nginx, .htaccess, правах доступа, нехватке памяти. Диагностика идёт через логи.
tail -50 /var/log/nginx/error.log
tail -f /var/log/nginx/error.log
tail -50 /var/log/php8.2-fpm.log
# Laravel
tail -50 /var/www/site/storage/logs/laravel.log
# WordPress
tail -50 /var/www/site/wp-content/debug.log
# Symfony
tail -50 /var/www/site/var/log/prod.log
# Создать тестовый файл:
cat > /var/www/site/info.php << 'EOF'
# Переименовать .htaccess
mv /var/www/site/.htaccess /var/www/site/.htaccess.bak
# Проверить логи Apache
tail -50 /var/log/apache2/error.log
# Исправить права:
chown -R www-data:www-data /var/www/site
find /var/www/site -type d -exec chmod 755 {} \;
find /var/www/site -type f -exec chmod 644 {} \;
php -m | grep -E "mbstring|xml|curl|json|mysqli|pdo"
# Установить недостающие
apt install php8.2-mbstring php8.2-xml php8.2-curl php8.2-mysql
systemctl restart php8.2-fpm
Частые причины 500
- Синтаксическая ошибка в PHP коде (Parse error)
- Отсутствует PHP модуль (mbstring, pdo, xml)
- Неправильные права доступа к файлам
- Ошибка в .htaccess (Apache)
- Нехватка памяти: PHP Fatal error: Allowed memory size exhausted
- Отсутствующие зависимости composer (vendor/)
- Ошибка подключения к базе данных
403 Forbidden
Сервер понял запрос но отказал в доступе. Это не проблема авторизации (это было бы 401), а проблема прав. Сервер не разрешает доступ к ресурсу по конфигурации, правам файловой системы или правилам файрвола/WAF.
ls -la /var/www/site/
ls -la /var/www/site/index.php
# Проверить всю цепочку до корня:
namei -l /var/www/site/index.php
# Проверить deny правила
grep -rn "deny" /etc/nginx/sites-enabled/
grep -rn "autoindex" /etc/nginx/sites-enabled/
# Проверить статус SELinux
getenforce
# Посмотреть AVC denials
ausearch -m AVC -ts recent
# Исправить контекст файлов
restorecon -Rv /var/www/
# Проверить свой IP
curl -s ifconfig.me
# Проверить Fail2ban
fail2ban-client status nginx-http-auth
# Разбанить свой IP
fail2ban-client set sshd unbanip YOUR_IP
tail -20 /var/log/nginx/error.log | grep "403"
tail -20 /var/log/nginx/access.log | grep "403"
open() ... failed (13: Permission denied) — проблема с правами файловой системы.
access forbidden by rule — правило deny в конфиге Nginx.
Частые причины 403
- Нет index файла и autoindex отключён
- Неправильные права доступа (нет r+x для www-data)
- Правило deny в конфиге Nginx
- SELinux блокирует доступ (CentOS/RHEL)
- IP заблокирован Fail2ban или файрволом
- WAF-правило (Cloudflare, ModSecurity)
- Файл принадлежит другому пользователю
Почта Письма не доходят / попадают в спам
Одна из самых частых проблем: контактные формы не отправляют письма, уведомления не доходят, или письма попадают в спам. Диагностика идёт от логов почты к DNS-записям.
tail -50 /var/log/mail.log
grep "status=sent" /var/log/mail.log | tail -5
grep "status=bounced" /var/log/mail.log | tail -5
mailq
dig example.com TXT | grep "v=spf1"
dig mail._domainkey.example.com TXT
dig _dmarc.example.com TXT
v=spf1 mx a ~all. DKIM — криптографическая подпись. DMARC — начните с p=none для мониторинга. Без этих трёх записей Gmail/Yahoo будут отклонять письма с 2024 года.
curl -s ifconfig.me
dig -x YOUR_IP +short
# WordPress: плагин WP Mail SMTP
# Подключить через SendGrid, Mailgun, Amazon SES
# Или SMTP вашего хостинга (порт 587 с TLS)
Почему письма попадают в спам
- Отсутствует SPF запись
- Отсутствует DKIM подпись
- Отсутствует DMARC запись
- PTR запись не настроена или не совпадает с hostname
- IP сервера в чёрном списке (Spamhaus, SORBS)
- Отправка с динамического IP (residential)
- Содержимое письма похоже на спам (ссылки, CAPS, вложения)
- Отсутствует обратный адрес или он не совпадает с доменом
SSL Проблемы с SSL сертификатами
Сертификат истёк, mixed content, невалидный сертификат, HSTS блокирует доступ. Диагностика и быстрое восстановление.
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates
certbot renew --force-renewal
nginx -t && systemctl reload nginx
# WordPress — заменить URL в БД:
wp search-replace "http://example.com" "https://example.com" --all-tables
# Nginx — автоматический upgrade:
add_header Content-Security-Policy "upgrade-insecure-requests;" always;
# Cron — автообновление дважды в день:
0 0,12 * * * certbot renew --quiet --post-hook "systemctl reload nginx"
# Проверить cron:
crontab -l
Частые проблемы с SSL
- Сертификат истёк — certbot не смог автообновить
- Mixed content — ресурсы загружаются по HTTP
- Сертификат не покрывает www поддомен
- Cloudflare проксирует и показывает свой сертификат
- HSTS блокирует доступ после истечения сертификата
- Цепочка сертификатов неполная (missing intermediate)
БД Ошибка подключения к базе данных
«Error establishing a database connection», «Too many connections», MySQL упал. Диагностика от базовых проверок к оптимизации.
systemctl status mysql
mysqladmin -u root -p ping
dmesg | grep -i "oom\|kill" | tail -10
# Проверить wp-config.php:
grep -E "DB_NAME|DB_USER|DB_PASSWORD|DB_HOST" /var/www/site/wp-config.php
# Тест подключения:
mysql -u db_user -p -h localhost db_name
# Проверить лимиты:
SHOW VARIABLES LIKE 'max_connections';
SHOW STATUS LIKE 'Threads_connected';
# Увеличить:
SET GLOBAL max_connections = 300;
# Проверить и восстановить:
mysqlcheck -u root -p --check --all-databases
mysqlcheck -u root -p --repair --all-databases
# Для InnoDB:
ALTER TABLE dbname.table_name FORCE;
Частые причины проблем с БД
- MySQL упал из-за OOM Killer (нехватка RAM)
- Неверные credentials в конфиге сайта
- max_connections достигнут — новые подключения отклоняются
- Таблица повреждена после abrupt shutdown
- Диск заполнен — MySQL не может писать
- Медленные запросы блокируют таблицу (LOCK WAIT)
- InnoDB buffer pool слишком мал — постоянные disk I/O
DNS DNS проблемы
Домен не резолвится, DNS propagation затянулся, сайт недоступен после смены DNS. Диагностика и ускорение propagation.
dig example.com A +short
dig example.com MX +short
dig example.com NS +short
dig example.com TXT +short
# Через конкретный DNS:
dig @8.8.8.8 example.com A +short
# Проверить TTL:
dig example.com A +noall +answer
# У разных провайдеров:
dig @8.8.8.8 example.com A +short
dig @1.1.1.1 example.com A +short
# Linux (systemd-resolved):
sudo systemd-resolve --flush-caches
# macOS:
sudo dscacheutil -flushcache
# Windows:
ipconfig /flushdns
Частые DNS проблемы
- DNS propagation ещё не завершена (ждите TTL)
- NS серверы указаны неправильно у регистратора
- A запись указывает на старый IP сервера
- Отсутствует www CNAME запись
- MX записи отсутствуют — почта не работает
- Cloudflare проксирует (оранжевый облако) — валидация SSL не проходит
- Локальный DNS кеш показывает старые данные