
Как Nginx находит файл: location, root, alias и try_files
Практически разбираем выбор location и построение пути к файлу в Nginx: root, alias, try_files, точные и префиксные маршруты, проверка и откат.
Содержание
Файл /var/www/example/assets/app.css существует, но Nginx всё равно отвечает 404. Чтобы найти причину, нужно отделить адрес, который прислал клиент, от пути на диске. Nginx сначала выбирает правило location, затем строит файловый путь через root или alias и проверяет результат через try_files.
У этих директив разные роли. location выбирает правило по адресу запроса. root добавляет этот адрес к базовому каталогу, а alias заменяет совпавшую часть адреса. try_files проверяет, какие из получившихся файлов действительно существуют. Разберём цепочку на одном статическом ресурсе.
Сначала отделите URI от пути
Клиент открывает следующий адрес. Он содержит протокол, домен, путь страницы и параметр после знака вопроса:
https://example.com/assets/css/app.css?v=2
Содержит URI /assets/css/app.css. Query string v=2 не участвует в выборе location. Файловый путь вроде /var/www/example/assets/css/app.css существует только на сервере и клиенту не сообщается.
Не вставляйте пользовательский URI напрямую в произвольный системный путь в скрипте. Nginx нормализует URI по своим правилам, а доступ должен оставаться внутри явно заданных каталогов.
Порядок выбора location
Правило location бывает точным, префиксным, регулярным и именованным. Следующие строки собраны для сравнения синтаксиса; это не готовый блок, который нужно целиком вставить в сайт:
location = /health { }
location /assets/ { }
location ^~ /downloads/ { }
location ~ \.php$ { }
location ~* \.(jpg|png|webp)$ { }
location @app { }
=— точное совпадение;- без модификатора — строковый префикс;
^~— префикс, после которого регулярные locations не проверяются;~и~*— чувствительное и нечувствительное к регистру regex-сопоставление;@name— именованный location для внутреннего перехода.
Сначала проверяется точное совпадение. Затем Nginx запоминает самый длинный подходящий префикс. Если он не защищён ^~, регулярные выражения проверяются в порядке записи; первое совпадение выбирается. Если regex не совпал, остаётся найденный префикс.
Не стройте большую конфигурацию из regex без необходимости. Префиксы проще читать, быстрее проверять логически и труднее случайно перекрыть.
Root сохраняет структуру адреса
Если каталог на диске повторяет путь в URL, используйте root. В этом примере базовый каталог задан всему серверу, а повторённая строка внутри location показывает то же значение явно:
server {
root /var/www/example;
location /assets/ {
root /var/www/example;
}
}
Для запроса /assets/css/app.css Nginx добавляет полный URI к базовому каталогу. В результате он попытается открыть следующий путь на диске:
/var/www/example/assets/css/app.css
Полный URI добавляется к root. Если один корень подходит всему сайту, задайте его на уровне server, а в locations оставьте только отличающееся поведение. Это сокращает дубли и риск расхождения путей.
Проверьте вычисление через переменные в временном диагностическом логе, а не публикуйте системный путь посетителю. Переменная $request_filename отражает текущий путь на основе URI и root/alias.
Alias заменяет часть адреса
Если публичный адрес и структура диска различаются, alias подменяет совпавший префикс. Здесь запросы к /media/ читаются из отдельного каталога загрузок:
location /media/ {
alias /srv/uploads/public/;
}
Для запроса /media/avatar.webp префикс /media/ заменяется каталогом из alias. Итоговый путь к файлу будет таким:
/srv/uploads/public/avatar.webp
Совпавшая часть /media/ заменяется значением alias. Завершающие слеши в обоих местах делают соответствие очевидным. Ошибка в одном слеше может построить неожиданный путь.
Если location и путь имеют одинаковый хвост, чаще понятнее root. alias полезен именно для замены структуры URI. В regex-location alias требует captures и ссылки на них; для начальной конфигурации избегайте такого сочетания.
Проверяйте файлы через try_files
Для обычного статического сайта перечислите допустимые варианты по порядку. В следующем правиле Nginx ищет файл, затем каталог и возвращает 404, если не нашёл ни того ни другого:
root /var/www/example/current;
location / {
try_files $uri $uri/ =404;
}
Nginx по очереди проверяет файл, каталог, затем возвращает 404. Слеш в $uri/ означает проверку каталога. Индекс обрабатывается отдельной директивой index.
Одностраничное приложение, маршруты которого обрабатывает JavaScript в браузере, иногда требует вернуть index.html для неизвестного пути. Такой fallback записывается последним вариантом:
location / {
try_files $uri $uri/ /index.html;
}
Это подходит только клиентской маршрутизации. Для обычного многостраничного сайта такой fallback вернёт 200 и главную страницу для несуществующего URL, что скрывает реальные 404 и ухудшает диагностику.
Последний параметр может быть кодом, URI или именованным location. URI запускает внутреннее перенаправление. Убедитесь, что fallback достигает файла или другого обработчика и не возвращается бесконечно в ту же ветку.
Отдельный каталог через alias
Публичные загрузки можно связать с каталогом, который находится вне основного root. В примере совпавшая часть /downloads/ заменяется путём /srv/files/public/:
location /downloads/ {
alias /srv/files/public/;
try_files $uri =404;
}
Сочетание alias и try_files требует особенно внимательного теста на вашей конфигурации, потому что путь строится в текущем контексте. Для простого публичного дерева иногда яснее выбрать структуру каталога, позволяющую использовать root.
Независимо от выбранной директивы рабочий процесс Nginx должен пройти каждый родительский каталог и прочитать файл. Следующие команды показывают права всего пути и проверяют чтение от имени стандартного пользователя www-data:
namei -l /srv/files/public/manual.pdf
sudo -u www-data test -r /srv/files/public/manual.pdf
Уточните пользователя Nginx. Не выдавайте 777; исправьте конкретного владельца, группу или право прохода.
Тестовая матрица маршрутов
До reload составьте ожидаемые ответы:
| URL | Ожидание |
|---|---|
/ |
главная, 200 |
/assets/app.css |
CSS, 200 и правильный Content-Type |
/assets/missing.css |
404 |
/docs/ |
индекс раздела или согласованный 404 |
/health |
точный ответ health location |
После сохранения конфигурации сначала проверьте всё дерево. Только успешный тест разрешает reload; затем запросите существующий и отсутствующий ресурс:
sudo nginx -t
sudo systemctl reload nginx
curl -I https://example.com/assets/app.css
curl -I https://example.com/assets/missing.css
Проверяйте не только код, но и Content-Type, редирект, Cache-Control и фактическое содержимое. 200 text/html для CSS часто означает, что SPA fallback скрыл отсутствующий файл.
Типовые ошибки
Дублирование части URI
location /images/ вместе с root /data/images строит /data/images/images/.... Если дерево не содержит повтор, выберите root /data или осознанный alias /data/images/.
Regex перехватил статику
Общий regex по расширению может заменить длинный префикс и применить другой root или заголовки. Посмотрите порядок и при необходимости используйте понятную и обоснованную структуру, а не добавляйте ^~ вслепую.
Неверный trailing slash
URI каталога без слеша может получить автоматический редирект в некоторых обработчиках, а alias со слешами может построить неверный путь. Тестируйте обе формы URL.
Файл есть, но ответ 403
Проверьте права всего пути, index и запреты доступа. Не меняйте location, если журнал прямо указывает на filesystem permissions.
Fallback возвращает 200 для любой ошибки
Разделите маршруты SPA и реальные статические ресурсы. Для assets используйте конечный =404, чтобы отсутствующий bundle не превращался в HTML.
Откат
Сохраните предыдущий конфигурационный файл или commit. При проблеме верните только изменённые locations, затем:
sudo nginx -t
sudo systemctl reload nginx
Повторите всю матрицу URL. Не удаляйте новое дерево файлов до подтверждения отката: иначе будет сложнее отличить ошибку конфигурации от отсутствующих данных.
Если запрос попадает не в ожидаемый location, восстановите путь его обработки через Nginx. Для нескольких доменов разделяйте виртуальные хосты, а файлы меняйте целостными атомарными релизами.
Первоисточники
- Модуль ngx_http_core_module — точные правила
location,root,aliasиtry_files. - Обработка запроса в Nginx — практические примеры выбора virtual server и location.
Самопроверка
Проверьте, что материал усвоен
Ответьте на все вопросы. Результат сохранится только в этом браузере и будет учтён в статистике прочитанных материалов.
Разбираем коротко
Частые вопросы
В чём главное различие root и alias в Nginx?
root добавляет URI к указанному корню, а alias заменяет совпавшую часть location заданным путём. Поэтому одинаковый URI даёт разные файловые пути, а завершающие слеши для alias особенно важны.
В каком порядке Nginx проверяет location?
Точное совпадение с = завершает поиск. Иначе запоминается самый длинный префикс, затем при обычных условиях регулярные выражения проверяются по порядку; первое совпавшее regex может заменить префикс.
Почему try_files иногда создаёт внутренний цикл?
Последний параметр выполняет внутреннее перенаправление. Если новый URI снова попадает в тот же fallback без достижимого файла или отдельного обработчика, запрос повторяется до защитного ограничения Nginx.


