К основному содержимому

Директива location в Nginx: порядок и приоритет правил

Nginx · 29.09.2026

Директива location определяет, какой блок конфигурации обработает конкретный URI внутри server block, описанного в статье о виртуальных хостах Nginx. Проблема в том, что location-блоков в одном сайте обычно несколько, и Nginx проверяет их не в порядке записи в файле, а по собственному алгоритму приоритета. Непонимание этого алгоритма — частая причина, почему правило вроде бы прописано, а не срабатывает.

Что делает директива location

Location сопоставляет URI запроса с шаблоном и, если совпадение найдено, применяет вложенные директивы: root, proxy_pass, try_files, заголовки и так далее. Один server block может содержать десятки location — для статики, для API, для админки, для конкретных расширений файлов.

Ключевая сложность в том, что несколько location могут одновременно подходить под один и тот же URI. Например, запрос /api/users/5 подходит и под location /api/, и под location ~ \.php$, если в пути встречается .php. Nginx должен выбрать один блок по строгим правилам.

Модификаторы location: =, ~, ~*, ^~ и без модификатора

Перед шаблоном location можно указать модификатор, который меняет тип сравнения и приоритет:

  • location = /path — точное совпадение URI, самый высокий приоритет.
  • location ^~ /path — префиксное совпадение с остановкой поиска регулярных выражений.
  • location ~ /path — совпадение по регулярному выражению с учётом регистра.
  • location ~* .php$ — совпадение по регулярному выражению без учёта регистра.
  • location /path — обычное префиксное совпадение без модификатора.

Порядок проверки правил Nginx

Nginx проверяет location не сверху вниз по файлу, а по алгоритму с чётким приоритетом:

1. Точное совпадение: location = /path
2. Префиксные location, среди них выбирается самый длинный совпавший префикс
3. Если у выбранного префикса стоит модификатор ^~ — поиск останавливается здесь
4. Иначе Nginx проверяет location с регулярными выражениями ~ и ~* по порядку в файле
5. Если совпадение по regexp нашлось — используется оно
6. Если нет — применяется тот самый длинный префикс из шага 2

Из этого следует правило: regexp location срабатывают только если их не заблокировал ^~ на более длинном префиксе, и порядок записи regexp location в файле имеет значение — Nginx берёт первое совпавшее сверху вниз.

Таблица приоритетов модификаторов

МодификаторТип сравненияПриоритет
=Точное совпадение URI1 — наивысший
^~Префикс, блокирует regexp2
~ и ~*Регулярное выражение3, по порядку в файле
без модификатораОбычный префикс4 — низший

Частые ошибки и конфликты правил

Классическая ошибка — location /images/ с обычным префиксом и рядом location ~* \.(jpg|png)$ для кэширования картинок. Если в /images/ лежат jpg-файлы, регулярное выражение победит префикс, даже если location /images/ записан раньше в файле — порядок в файле важен только для regexp-блоков между собой.

Вторая частая ошибка — забыть ^~ перед location для статики, из-за чего запрос к статическому файлу неожиданно попадает в regexp-блок с proxy_pass на PHP-FPM. Подробнее о передаче запросов на backend — в статье про reverse proxy на Nginx, а о финальной отдаче файлов — в статье об отдаче статики.

Практические примеры location

Типичный набор правил для сайта со статикой, API и редиректами, который также перекликается со статьёй про rewrite и return в Nginx:

location = /favicon.ico { access_log off; log_not_found off; }
location ^~ /assets/ { expires 30d; }
location ~* \.(css|js|woff2)$ { expires 7d; }
location /api/ { proxy_pass http://127.0.0.1:3000; }
location / { try_files $uri $uri/ /index.php?$args; }

Здесь /favicon.ico обрабатывается первым по точному совпадению, /assets/ с ^~ гарантированно не отдаётся regexp-блокам, а остальные regexp и общий location проверяются в порядке из алгоритма выше.

Как проверить, какой location сработал

Чтобы убедиться, что запрос попадает в нужный блок, добавьте временный заголовок add_header X-Location-Debug "имя блока"; в каждый спорный location и посмотрите заголовки ответа через curl -I. После правок обязательны nginx -t и systemctl reload nginx.

  1. Перечислите все location в server block и отметьте модификаторы.
  2. Проверьте, нет ли regexp-блока, который случайно перекрывает статику с ^~.
  3. Проверьте порядок regexp-location между собой — Nginx берёт первый совпавший.
  4. Прогоните nginx -t перед reload на боевом сервере.

Приоритет location в Nginx — не порядок в файле, а строгий алгоритм: точное совпадение, затем префикс с ^~, затем regexp по порядку записи, и только потом обычный префикс. Запоминание этой последовательности избавляет от часов отладки конфигурации.

← Назад в базу знаний Задать вопрос поддержке