Главная >> Инструкции >> Ошибка 404 not found Nginx

Ошибка 404 not found Nginx

Веб-серверы Nginx и Apache мало похожи друг на друга, и их отличия касаются не только особенностей подключения пользователей, но и обработки URL на сервере. Очень часто новые пользователи Nginx получают ошибку 404 для URL, которые, по сути, должны были бы работать.

В этой статье рассмотрим, почему возникает ошибка "404 not found Nginx", а также способы её устранения и отладки.Мы не будем разбираться с ситуацией, когда файла действительно нет на сервере - это решение, не требующее пояснений. Мы рассмотрим проблему обработки location в Nginx.


Содержание статьи

Почему возникает ошибка 404 в Nginx

Давайте сначала разберёмся, как обрабатываются URL в Nginx. Когда веб-сервер определил, к какому блоку server (сайту) нужно передать запрос пользователя, просматриваются все префиксные блоки location и выбирается тот, который подходит лучше всего. Например, рассмотрим стандартную конфигурацию для WordPress. Здесь префиксные location отмечены зелёным, а с регулярным выражением - оранжевым:

location / {
index index.html index.php;
}
location /favicon.ico {
access_log off;
}
location ~* \.(gif|jpg|png)$ {
expires 30d;
}
location ~ \.php$ {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
}

Префиксные локейшены всегда начинаются с символа /. Регулярные же содержат символы регулярных выражений: ~ $ ^ * и так далее. Если пользователь запрашивает favicon.ico, то будет выбран второй location, так как он лучше всего соответствует запросу, при любом другом запросе будет выбран location /, так как он соответствует всем запросам, а других префиксных location у нас нет. Это просто, а дальше начинается магия. После того, как был найден нужный location, Nginx начинает проверять все регулярные выражения в порядке их следования в конфигурационном файле.

При первом же совпадении Nginx останавливает поиск и передаёт управление этому location. Или, если совпадений не было найдено, используется ранее обнаруженный префиксный location. Например, если запрос заканчивается на .php, то первый location будет проигнорирован, а управление передастся четвёртому (~ \.php$)

Таким образом, любое неверно составленное регулярное выражение в любой части конфигурационного файла может полностью всё сломать. Поэтому разработчики рекомендуют по минимум использовать регулярные выражения. Что касается вложенных location, то обрабатываются они так же как и основные, только уже после передачи управления в нужный location. Путём чтения конфигурационного файла понять, какой location вызывает 404 сложно, поэтому, чтобы исправить ошибку, нам понадобиться режим отладки Nginx.

Как включить режим отладки Nginx?

Сначала нам необходимо установить версию Nginx с поддержкой отладки. Чтобы проверить, поддерживает ли ваша текущая версия этот режим, наберите:

nginx -V

В выводе должна быть строчка "--with-debug". Если её нет, значит отладка не поддерживается, и надо установить версию с поддержкой. В CentOS такой пакет называется nginx-debug. Для его установки наберите:

sudo yum install nginx-debug

Теперь появился ещё один исполняемый файл, и он собран уже с поддержкой отладки:

nginx-debug -V

Откройте конфигурационный файл вашего сайта или глобальный конфигурационный файл, если вы не задавали настройки логов отдельно для каждого сайта, и в конце стоки error_log замените error на debug:

error_log /var/log/nginx/domains/test.losst.pro.error.log debug

Останавливаем обычную версию и запускаем версию с отладкой:

systemctl stop nginx
systemctl start nginx-debug

Как исправить "404 Not Found Nginx"?

1. Регулярные выражения

Как я уже сказал выше, самой частой проблемой, которая вызывает 404, являются регулярные выражения. Смотрим, что происходит в лог файле:

tail -f /var/log/nginx/domains/test.losst.pro.error.log

Видим, что серверу пришёл запрос /vstats. Дальше он проверяет location: /, /robots.txt, /vatsts/, /site-control/. Здесь уже можем понять, в чём проблема - промазали на один слеш. Дальше проверяются все регулярные выражения, и, так как в них ничего найдено не было, выбирается location /.

Далее директива try_files пытается найти файл /vstats, не находит и ищет index.php, который, в свою очередь, возвращает 404.

Если мы наберём, то что ожидает видеть Nginx - /vstats/, то откроется наша страница статистики.

Если мы добавим к конфигурационному файлу ещё один location с регулярным выражением, например:

location ~* {
try_files $uri $uri/ =404;
}

То абсолютно все запросы будут обрабатываться именно этим регулярным выражением и, естественно, что ничего работать не будет. Видим, что приходит запрос /vstats/:

Он совпадает с префиксным location, но потом Nginx видит наше регулярное выражение и передаёт управление ему.

Поэтому будьте очень осторожны с регулярными выражениями, если они вам нужны, то размещайте их только внутри префиксных location, чтобы ограничить их область действия этим location, иначе может возникнуть ошибка 404 nginx.

2. Недостаточно памяти

Если php-скрипту не хватило оперативной памяти для выполнения, и его процесс был убит операционной системой, то Nginx тоже может вернуть ошибку 404. Такое поведение вы будете наблюдать, когда скрипт очень долго выполняется, а потом появляется "404 Not Found" или страница ошибки вашего движка. Обычно эта неисправность тоже видна в отладочном логе.

Решить такую проблему можно, освободив память на сервере, часто такое может возникать из-за утечек памяти в php, когда процессы php-fpm занимают почти всю память на сервере. Поэтому перезапуск php-fpm решает проблему:

systemctl restart php-fpm

Чтобы избежать этой проблемы в будущем, можно настроить автоматический перезапуск процессов после обработки определённого количества запросов. Например каждые 200 запросов:

vi /etc/php-fpm.d/www.conf

pm.max_requests = 200

3. Не найден index

Если вы запрашиваете URL вида /vstats/, но в настройках Nginx не указан файл index, который нужно использовать для этой ссылки, то у вас ничего не выйдет, и вы получите 404. Вы можете добавить директиву index в ваш location:

location / {
index index.php index.html index.htm;
}

Или сразу в server, в Nginx все location наследуют директивы, установленные в server.

4. Другие проблемы

Подобных проблем, вызывающих 404 в Nginx, может быть очень много, но все они решаемы, и всё, что нужно для их решения, есть в отладочном логе Nginx. Просто анализируйте лог и на основе этого вносите исправления.

Выводы

В этой статье мы рассмотрели основные причины, из-за которых может возникнуть ошибка 404 not found Nginx. Как видите, может быть много проблем, но всё достаточно просто решается. А с какими проблемами, вызывающими эту ошибку, вы сталкивались? Как их решали? Напишите в комментариях!

Creative Commons License
Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .

2 комментария к “Ошибка 404 not found Nginx”

  1. Замутил торрент-качалку transmission за проксей nginx. Нашёл в тырнетах конфиг для оной цели, воткнул, мальца подправил - работает. Прикрутил ещё самописный сертификат к нему на всякий, тож работает. Всякие ваши let's encrypt и уж тем паче платные мне не требуются на данный момент, т.к. окромя себя любимого не хочу видеть на странице авторизации transmission никого. Терь при при вводе в браузере что-то наподобие "https://myservak.gov", я попадаю в свой трансмишн. Nginx очень порадовал возможностью прикрывать своей ssl-грудью сервисы, неспособные защитить себя от перехвата злобных гоблинов. Беда только в том, что не шарю в ём покамест. Потому запрашиваю помощи знающих, которые бескорыстно и из лучших человеческих побуждений смогут мне подсказать, каким образом нужно подправить мой конфиг, шоб я ещё нагрузил nginx веб-страничкей с какой-нить не нужной никому окромя мя инфой. Чтобы по ссылке https://myservak.gov я попадал на какую-нить хтмл-страничку "Здравствуйте, как поживаете? Добро пожаловать на мой личный сайт", а по ссылке типа https://myservak.gov/transmission вылазила форма авторизации в трансмишене. Конфиг прилагаю ссылкой:
    https://paste.pound-python.org/show/JrixC7a70e6WJ8kyEHwD/

    Ответить
  2. А я на Расбери на Дебиан пытаюсь поднять в докере сайт на ASP.Net Core с выходом в тырьтырьнет... пока безрезультатно! (выход в тырьтырьнет) что-то с пробросом портов на роутере...

    Ответить

Оставьте комментарий