Справочник

location в nginx: как выбирается блок для адреса

Блок location задаёт правила для части адресов сайта. Для каждого запроса nginx выбирает один блок: сначала ищет самый длинный подходящий префикс, затем проверяет регулярные выражения — первое совпавшее побеждает, а если ни одно не подошло, работает найденный префикс.

≈ 5 мин чтения
Содержание 9

Что сделать прямо сейчас

  1. Команды вводятся на сервере: подключитесь к нему по SSH ([как подключиться](/instrukcii/kak-podklyuchitsya-k-vps-po-ssh/)) и набирайте их в том же окне.
  2. Откройте файл сайта: sudo nano /etc/nginx/sites-available/example.com. Вместо example.com — имя файла вашего сайта: список покажет ls /etc/nginx/sites-enabled/. Если система спросит пароль, введите пароль своего пользователя на сервере. Символы при вводе не видны — наберите пароль и нажмите Enter.
  3. Найдите блоки location: Ctrl+W, слово location, Enter. К следующему — Ctrl+W и Enter ещё раз.
  4. Добавьте или поправьте блок внутри server — перед последней закрывающей скобкой }. Второй блок с тем же адресом не пишите: поправьте тот, что уже есть.
  5. Сохраните файл — Ctrl+O, Enter, затем Ctrl+X — и проверьте настройки: sudo nginx -t. В ответе должны быть слова syntax is ok и test is successful. Тогда примените их: sudo systemctl reload nginx. Если команда ничего не ответила, настройки применены.

Виды location

ЗаписьКак сравнивает адресПример адреса
location /images/адрес начинается с этой строки/images/logo.png
location = /адрес совпадает целиком; совпал — поиск сразу останавливаетсятолько главная /
location ^~ /static/как префикс, но если он оказался самым длинным, регулярные выражения не проверяются/static/app.js
location ~ \.php$регулярное выражение, большие и маленькие буквы различаются/index.php, но не /INDEX.PHP
location ~* \.jpe?g$регулярное выражение, регистр букв не важен/photo.jpg и /PHOTO.JPEG
location @appименованный: по адресу не выбирается, в него передают запрос из try_files или error_page—

nginx сравнивает только путь — часть адреса до знака ?. Параметры после него в выборе не участвуют. Перед сравнением путь приводится к одному виду: коды вида %20 раскодируются, /a/../b превращается в /b, двойные слэши склеиваются.

Как nginx выбирает блок

  1. Сравнивает путь со всеми префиксными location. Совпадение с location = — сразу берёт этот блок. Иначе запоминает самый длинный совпавший префикс.
  2. Если у этого префикса стоит ^~, берёт его — регулярные выражения не проверяет.
  3. Проверяет регулярные выражения по порядку, как они записаны в файле. Первое совпавшее побеждает.
  4. Если ни одно регулярное выражение не подошло, берёт запомненный префикс.

Порядок префиксных блоков в файле не важен — побеждает самый длинный. Порядок регулярных выражений важен — побеждает первое.

Пример

location = / {               # блок А
}
location / {                 # блок Б
}
location /docs/ {            # блок В
}
location ^~ /img/ {          # блок Г
}
location ~* \.(png|jpg)$ {   # блок Д
}
АдресБлокПочему
/Аточное совпадение
/about.htmlБподошёл только префикс /
/docs/guide.htmlВсамый длинный префикс, регулярное выражение не совпало
/img/logo.pngГсамый длинный префикс с ^~: регулярные выражения не проверялись
/docs/photo.jpgДпрефикс /docs/ запомнен, но совпало регулярное выражение и победило

Вложенные location

Блок location можно написать внутри другого. Внутренний префикс должен начинаться с внешнего: внутри location /blog/ можно location /blog/img/, а location /img/ nginx не примет. Регулярные выражения внутри могут быть любыми:

location /blog/ {
    location ~* \.jpe?g$ {
        expires 30d;
    }
}

Здесь картинки JPEG из /blog/ браузер будет хранить у себя 30 дней — подробнее о expires. Внутри location = и location @имя других блоков быть не может, а именованный location пишут только прямо в server.

Слэш в конце и переадресация 301

Если location записан со слэшем в конце, например location /app/, и запросы из него уходят приложению через proxy_pass или в PHP через fastcgi_pass, то на адрес без слэша — /app — nginx ответит переадресацией 301 на /app/. Если это не нужно, добавьте отдельный блок для точного адреса:

location = /app {
    proxy_pass http://127.0.0.1:3000;
}

Как работает proxy_pass и при чём тут слэш в конце адреса — proxy_pass в nginx.

Ошибки и как их исправить

Что видитеЧто делать
duplicate location "…"два блока с одним и тем же адресом
location "…" is outside location "…"внутренний префикс не начинается с внешнего: поправьте адрес или вынесите блок наружу
location "…" cannot be inside the exact location "…"внутри location = других блоков быть не может — вынесите блок наружу
"location" directive is not allowed herelocation стоит вне блока server
правило из location не срабатываетадрес перехватил другой блок: регулярное выражение выше по файлу или префикс с ^~

Какой блок обработал запрос, проще всего проверить своим заголовком: добавьте в location строку add_header X-Block docs; и посмотрите ответ командой curl -I https://example.com/docs/guide.html. После проверки строку уберите. Как работает add_header — на отдельной странице.

Источники

Сверено 14 октября 2026 года.

Что почитать дальше