Что такое ошибка Nginx и как с ней работать
Представь, что Nginx — это диспетчер на стройке. Он принимает запросы от клиентов (прорабов) и передает их рабочим (бэкенд-приложениям, вроде PHP-FPM или Node.js). Ошибка Nginx — это сигнал о том, что в этой цепочке что-то пошло не так. Давай разберем самые частые коды ошибок, их причины и способы решения, как опытный DevOps.
Диагностика: с чего начать при любой ошибке
Прежде чем лечить симптомы, нужно понять причину. Вот твой универсальный чек-лист:
- Проверь логи Nginx: Основной источник истины. Логи ошибок и доступа.
- Проверь логи бэкенда: Приложения (PHP, Python, БД) часто пишут свои ошибки.
- Убедись, что процессы живы: Работает ли сам Nginx и upstream-сервисы?
- Проверь конфигурацию: Одна опечатка может сломать всё.
# Основные команды для диагностики
# 1. Проверка синтаксиса конфигурации
sudo nginx -t
# 2. Просмотр логов ошибок в реальном времени (замени путь на свой)
tail -f /var/log/nginx/error.log
# 3. Просмотр логов доступа
tail -f /var/log/nginx/access.log
# 4. Проверка статуса службы Nginx
sudo systemctl status nginx
# 5. Проверка, слушает ли Nginx порты
sudo ss -tulpn | grep nginx
Ошибка 502 Bad Gateway: Бэкенд не отвечает
Самая частая и неприятная ошибка 502 Nginx. Nginx получил запрос, пошел к бэкенду (например, PHP-FPM или другому серверу), но тот не ответил вовремя или ответил невнятно.
- Бэкенд-сервис (PHP-FPM, Gunicorn, Apache) упал или не запущен.
- Неверные настройки сокета или порта в конфиге Nginx.
- Бэкенд исчерпал ресурсы (память, workers) и не может обработать запрос.
- Слишком маленькие таймауты между Nginx и бэкендом.
- Проблемы с файрволом или сетевыми правилами.
Как исправить 502 ошибку Nginx
- Проверь, жив ли бэкенд:
bash
# Для PHP-FPM sudo systemctl status php8.1-fpm # или твоя версия php # Для Gunicorn sudo systemctl status gunicorn # Просто проверка, слушает ли порт/socket sudo ss -tulpn | grep :9000 # или твой порт бэкенда - Увеличь таймауты в конфиге Nginx, если бэкенд медленный:
nginx
location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # Увеличиваем таймауты fastcgi_read_timeout 300s; fastcgi_send_timeout 300s; proxy_read_timeout 300s; proxy_connect_timeout 300s; # ... остальные директивы } - Проверь корректность upstream-блока (если используешь):
nginx
upstream backend { server 127.0.0.1:8080; # Убедись, что порт правильный! # server unix:/tmp/backend.sock; # Или сокет keepalive 32; # Рекомендуется для производительности }
Ошибка 504 Gateway Timeout: Таймаут соединения
Ошибка 504 Nginx похожа на 502, но здесь Nginx явно говорит: "Я ждал ответа от бэкенда, но не дождался в отведенное время". Часто возникает при тяжелых запросах к БД или внешним API.
Решение проблемы 504 Timeout
- Увеличить таймауты proxy в основном конфиге или location-блоке:
nginx
http { # Глобальные настройки таймаутов proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 120s; # Самый важный для 504! send_timeout 60s; # ... } # Или для конкретного location location /api/ { proxy_pass http://backend; proxy_read_timeout 300s; # Даем больше времени на медленный API } - Оптимизировать бэкенд: Если запросы выполняются дольше 30-60 секунд, это повод пересмотреть логику приложения, добавить кеширование или индексы в БД.
- Проверить нагрузку на сервер: Возможно, не хватает CPU или памяти.
bash
# Мониторим ресурсы htop free -h df -h # Проверяем место на диске
Ошибка 403 Forbidden: Доступ запрещен
Ошибка 403 Nginx означает, что Nginx понял запрос, но намеренно отказывается его выполнять из-за недостаточных прав. Это не ошибка конфигурации в чистом виде, а ожидаемое поведение при нарушении правил доступа.
- Неверные права доступа к файлам и папкам (permissions).
- Ограничения по IP-адресу в конфиге (
allow/deny). - Отсутствие индексного файла (index.html, index.php) при выключенном
autoindex. - Попытка доступа к системному файлу, доступ к которому запрещен конфигурацией.
Исправление ошибки 403
- Проверь права доступа (permissions): Nginx-процесс (обычно пользователь
www-dataилиnginx) должен иметь право на чтение файлов.bash# Типичная правильная структура прав для статики sudo chown -R www-data:www-data /var/www/my-site sudo chmod -R 755 /var/www/my-site # Для папок с загрузками (куда нужно писать) sudo chmod -R 775 /var/www/my-site/uploads - Убедись, что индексный файл существует и указан в конфиге:
nginx
server { listen 80; server_name example.com; root /var/www/my-site; index index.html index.php; # Вот этот список файлов # Если нужно разрешить листинг каталогов (осторожно!) # autoindex on; } - Проверь блокировку по IP: Ищи в конфигах директивы
allowиdeny.nginxlocation /admin/ { allow 192.168.1.0/24; # Разрешено только с этой сети allow 10.0.0.1; # И этот конкретный IP deny all; # Всем остальным - 403 }
Ошибка 404 Not Found: Файл не найден
Ошибка 404 Nginx — классика. Nginx не может найти запрошенный ресурс по указанному пути. Часто возникает после деплоя, при смене структуры URL или из-за опечаток.
Что делать, если файл не найден
- Проверь корневую директорию (root) и путь: Самая частая причина.
nginx
server { # Убедись, что root ведет в правильную папку! root /var/www/my-site/public; # Часто статика лежит в public/ # А не просто /var/www/my-site location / { try_files $uri $uri/ /index.php?$query_string; } } - Директива
try_files— твой лучший друг: Она позволяет гибко обрабатывать запросы.nginx# Классика для SPA (React, Vue) или CMS location / { try_files $uri $uri/ /index.html; # Для SPA # try_files $uri $uri/ /index.php?$args; # Для WordPress/Laravel } # Для статики с fallback location /images/ { try_files $uri /static/default.png; } - Включи логи, чтобы видеть полный запрошенный путь:
Затем проверь:nginx
server { # ... # В access.log будет полный путь access_log /var/log/nginx/access.log combined; }bashtail -f /var/log/nginx/access.log | grep 404
Ошибка 500 Internal Server Error: Проблема в бэкенде
Когда ты видишь ошибку 500 Nginx, знай: Nginx тут почти не при чем. Он успешно передал запрос бэкенду (например, PHP), но тот сгенерировал фатальную ошибку и не вернул нормальный ответ. Nginx просто ретранслирует этот "внутренний" сбой клиенту.
Диагностика Internal Server Error
- Смотри логи бэкенда, а не Nginx!
bash
# Логи PHP-FPM sudo tail -f /var/log/php8.1-fpm.log # Или путь из конфига php-fpm # Логи приложения (например, Laravel) tail -f /var/www/my-site/storage/logs/laravel.log # Логи Python (Gunicorn/Uvicorn) sudo journalctl -u gunicorn -f - Проверь синтаксис PHP-файлов (если используешь PHP):
bash
# Быстрая проверка синтаксиса всех PHP файлов find /var/www/my-site -type f -name "*.php" -exec php -l {} \; - Убедись, что переменные окружения и права на запись настроены правильно. Часто 500 ошибка возникает из-за того, что приложение не может записать в кеш-папку или сессии.
Другие частые ошибки Nginx и их решения
400 Bad Request: Неверный запрос
Ошибка 400 Nginx говорит о том, что клиент отправил некорректный HTTP-запрос (например, с неправильными заголовками или слишком длинным URL).
- Причина: Слишком длинные заголовки (Cookie, User-Agent).
- Решение: Увеличить
large_client_header_buffers.nginxhttp { large_client_header_buffers 4 32k; # По умолчанию 4 8k }
413 Request Entity Too Large: Файл слишком большой
Ошибка 413 Nginx возникает при загрузке файлов, размер которых превышает лимит, установленный в client_max_body_size.
# В http, server или location блоке
http {
client_max_body_size 100M; # Разрешаем загрузку до 100 МБ
}
# Или только для API загрузки
location /upload/ {
client_max_body_size 500M;
# ...
}
405 Method Not Allowed: Метод не разрешен
Ошибка 405 Nginx — клиент использует HTTP-метод (например, POST), который не разрешен для данного URL. Часто возникает при неправильной настройке обработки статики.
# Статику лучше обслуживать только GET/HEAD
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
# Явно ограничиваем методы для статики
limit_except GET HEAD {
deny all;
}
}
499 Client Closed Request: Клиент разорвал соединение
Ошибка 499 Nginx — не совсем ошибка сервера. Клиент (браузер или скрипт) закрыл соединение, пока Nginx еще обрабатывал запрос. Часто возникает при слишком долгих запросах, когда у клиента срабатывает свой таймаут.
- Что делать: Уменьшить время обработки запросов на бэкенде, оптимизировать логику. Или увеличить таймауты на стороне клиента, если это твой API-клиент.
Сводная таблица ошибок Nginx
| Код ошибки | Причина | Где искать решение | Приоритет |
|---|---|---|---|
| 502 Bad Gateway | Бэкенд не отвечает | Статус бэкенда, таймауты, upstream | Высокий |
| 504 Gateway Timeout | Таймаут ожидания бэкенда | proxy_read_timeout, оптимизация бэкенда |
Высокий |
| 403 Forbidden | Нет прав доступа | Permissions, allow/deny, index файлы |
Средний |
| 404 Not Found | Ресурс не найден | root, try_files, путь в запросе |
Средний |
| 500 Internal Server Error | Ошибка в бэкенд-приложении | Логи PHP/Python, синтаксис, права на запись | Высокий |
| 413 Request Too Large | Превышен размер загружаемого файла | client_max_body_size |
Низкий |
Часто задаваемые вопросы (FAQ)
Где находятся логи Nginx по умолчанию?
В большинстве дистрибутивов Linux логи лежат в /var/log/nginx/. Основные файлы: error.log (ошибки) и access.log (доступ). Точный путь можно проверить в конфиге: sudo nginx -T | grep access_log.
Как перезагрузить конфиг Nginx без даунтайма?
Используй команду sudo nginx -s reload. Она загружает новую конфигурацию, плавно перезапуская worker-процессы без разрыва существующих соединений. Всегда проверяй конфиг перед этим: sudo nginx -t.
Почему после исправления конфига ошибка не исчезает?
1. Не забыл сделать nginx -s reload? 2. Проверь кеш браузера (открой в инкогнито). 3. Возможно, ошибка кешируется на уровне CDN или прокси. 4. Смотри актуальные логи после запроса: tail -f /var/log/nginx/error.log.
В чем разница между 502 и 504 ошибкой?
502 Bad Gateway — бэкенд ответил, но ответ был некорректным или он вообще не запущен. 504 Gateway Timeout — бэкенд слишком долго думал, и Nginx прекратил ждать. 502 чаще связана с доступностью сервиса, 504 — с его производительностью.
Как настроить кастомную страницу ошибок?
Используй директиву error_page:
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /404.html {
internal;
root /usr/share/nginx/html;
}
Заключение: Алгоритм действий при любой ошибке
- Определи код ошибки (502, 504, 403, 404, 500 и т.д.).
- Зайди в логи:
sudo tail -f /var/log/nginx/error.log. - Проверь конфиг:
sudo nginx -t. - Сверься с таблицей выше для быстрого поиска частых причин.
- Для 5xx ошибок смотри логи бэкенда (PHP-FPM, приложения).
- Вноси изменения и тестируй:
sudo nginx -s reload. - Документируй решение. Однажды найденная причина может повториться.
Помни: ошибка Nginx — это не катастрофа, а сигнал. Систематический подход к диагностике, понимание архитектуры (клиент ↔ Nginx ↔ бэкенд) и умение читать логи превратят тебя из того, кто боится 502 ошибки, в того, кто решает ее за 5 минут. Удачи в отладке!