location в nginx: как выбирается блок для адреса
Блок location задаёт правила для части адресов сайта. Для каждого запроса nginx выбирает один блок: сначала ищет самый длинный подходящий префикс, затем проверяет регулярные выражения — первое совпавшее побеждает, а если ни одно не подошло, работает найденный префикс.
Содержание 9
Что сделать прямо сейчас
- Команды вводятся на сервере: подключитесь к нему по SSH ([как подключиться](/instrukcii/kak-podklyuchitsya-k-vps-po-ssh/)) и набирайте их в том же окне.
- Откройте файл сайта:
sudo nano /etc/nginx/sites-available/example.com. Вместо example.com — имя файла вашего сайта: список покажетls /etc/nginx/sites-enabled/. Если система спросит пароль, введите пароль своего пользователя на сервере. Символы при вводе не видны — наберите пароль и нажмите Enter. - Найдите блоки location: Ctrl+W, слово
location, Enter. К следующему — Ctrl+W и Enter ещё раз. - Добавьте или поправьте блок внутри server — перед последней закрывающей скобкой
}. Второй блок с тем же адресом не пишите: поправьте тот, что уже есть. - Сохраните файл — 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 выбирает блок
- Сравнивает путь со всеми префиксными location. Совпадение с
location =— сразу берёт этот блок. Иначе запоминает самый длинный совпавший префикс. - Если у этого префикса стоит
^~, берёт его — регулярные выражения не проверяет. - Проверяет регулярные выражения по порядку, как они записаны в файле. Первое совпавшее побеждает.
- Если ни одно регулярное выражение не подошло, берёт запомненный префикс.
Порядок префиксных блоков в файле не важен — побеждает самый длинный. Порядок регулярных выражений важен — побеждает первое.
Пример
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 here | location стоит вне блока server |
| правило из location не срабатывает | адрес перехватил другой блок: регулярное выражение выше по файлу или префикс с ^~ |
Какой блок обработал запрос, проще всего проверить своим заголовком: добавьте в location строку add_header X-Block docs; и посмотрите ответ командой curl -I https://example.com/docs/guide.html. После проверки строку уберите. Как работает add_header — на отдельной странице.
Источники
- Документация nginx: location — префиксы и регулярные выражения, модификаторы =, ^~, ~ и ~*, порядок выбора, вложенные и именованные блоки, переадресация 301 на адрес со слэшем.
- Исходный код nginx 1.24.0: ngx_http_core_module.c — функция ngx_http_core_find_location сравнивает путь запроса без параметров; тексты is outside location и cannot be inside the exact location.
- Документация nginx: руководство для начинающих — простые и блочные директивы, контексты main, events, http, server и location.
Сверено 14 октября 2026 года.
Что почитать дальше
- Настройки nginxкак устроены файлы и блоки, главные директивы.
- try_files в nginxчто отдать, если файла нет.
- root и alias в nginxв какой папке искать файлы.
- Ошибка duplicate locationдва одинаковых блока location.
- server_name в nginxкак nginx выбирает сайт.