В этой статье погрузимся в основы конфигурации веб‑сервера Angie — директиву location
. Она используется во всех конфигурациях при работе с HTTP‑модулем и отвечает за разделение настроек обработки запросов по URL. В том числе, с помощью location
происходит разделение запросов на статические и динамические. Начнём с последнего: разберёмся, что такое динамические и статические запросы.
Навигация по циклу
Настройка location в Angie. Разделение динамических и статических запросов.
Видеоверсия
Для вашего удобства подготовлена видеоверсия этой статьи, доступна на Rutube, VKVideo и YouTube.
Динамические и статические запросы
Стандартная архитектура веб‑приложения на сегодня включает в себя схему с обратным прокси (может называться «фронт‑сервер») и сервером приложений («бэкенд»). Например, это может быть связка Angie и PHP‑FPM.
В такой схеме фронт‑сервер обслуживает статические запросы — отдаёт файлы с диска, а бэкенд исполняет серверный код (например, PHP) и передаёт результат фронту для ответа клиенту.
Выделение location для статики
Со стороны клиента отличить статические и динамические запросы с гарантированной точностью невозможно, но можно предположить, что к статическим запросам для большинства веб-приложений можно отнести:
CSS файлы;
JS файлы;
файлы подключаемых шрифтов;
изображения;
аудио- и видеофайлы;
статические текстовые файлы (txt, html, xml);
прочие файлы для скачивания (архивы, бинарные файлы и т. д.)
Соответственно, для корректной конфигурации веб‑приложения в Angie необходимо выделить для всех этих категорий свои location, в которых будут определены правила обработки таких запросов. Например, если в приложении есть каталог /js, который содержит JS‑ресурсы, то его конфигурация может выглядеть так:
location /js/ {
root /var/www/html;
}
Это так называемый префиксный location, то есть все запросы (если не будет более приоритетных location), адрес в которых начинается с /js/, будут обрабатываться с такой конфигурацией. Директива root здесь приведена для наглядности, на самом деле мы можем определить root на уровне сервера и оставить блок конфигурации пустым, так как значение директивы будет наследоваться с более высокого уровня.
В некоторых приложениях мы не можем полагаться на четкую структуру директорий и адресов ресурсов. Например, статические файлы могут находиться в любой точке адресной структуры приложения. В таком случае мы можем применить location на основе регулярных выражений (regex). Обычно определение статики работает на основе расширений файлов в URL:
location ~* \.(?:css|js|woff2?|jpe?g|gif|png|txt|pdf)$ {
root /var/www/html;
}
В этом примере мы сопоставляем адрес ресурса с регулярным выражением без учёта регистра (~*
), ищем в окончании адреса ($
) знак точки (\.
) и одно из расширений. Напоминаю, что GET‑параметры запроса не входят в адрес, то есть запрос /1.css?test=2
также попадёт в этот location.
Основной недостаток такого подхода: нужно заранее предусмотреть все возможные расширения статических файлов.
Выделение location для динамики
Динамические запросы как правило определяются самым низкоприоритетным location /. Например:
location / {
proxy_pass http://127.0.0.1:9090/;
}
Мы описываем все статические запросы, а всё остальное отправляем на бэкенд. Второй вариант выделения динамических запросов — регулярные выражения на расширение файлов скриптов:
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
Попасть в такой location можно либо при прямом вызове скрипта (/info.php
), либо при обработке запроса к директории (/shop/
) с директивой index index.php
. Однако в современных веб‑приложениях допустимы произвольные (человекочитаемые) URL, поэтому для них сложно составить правильный набор location
, и становится сложно отличить статический запрос от динамического. Здесь на помощь приходит директива try_files
, которая позволяет проверить наличие файлов на диске, соответствующих адресу в запросе и в случае их отсутствия отправить обработку в другой location или сразу на скрипт:
location / {
try_files $uri $uri/ /index.php?$args;
}
location / {
try_files $uri $uri/ @bitrix;
}
location @bitrix {
fastcgi_pass 127.0.0.1:9001;
include fastcgi.conf;
}
В этих примерах запрос попадает в location /
, там происходит попытка обработать запрос как URI, далее как директорию и дальше происходит внутреннее перенаправление на скрипт (/index.php?$args
) или в именованный location (@bitrix
).
Есть еще одна разновидность разделения динамических и статических запросов с использованием if
. Использование блоков if
в целом не рекомендуется из-за их непредсказуемого поведения в сочетании с директивами других модулей (не rewrite), но такая конструкция также возможна:
location / {
root /var/www;
index index.php;
if (!-e $request_filename) {
rewrite ^(.+)$ /index.php?q=$1 last;
}
}
В примере выше происходит проверка наличия файла через if
. Если файл есть, то он будет обслужен как статический запрос. Если файла нет, то запрос будет перенаправлен на /index.php?q=$1
.
Для создания корректной конфигурации необходимо разобрать приоритеты различных типов location. Перейдём к разбору этого аспекта.
Приоритеты location
Ранее мы уже использовали несколько типов location
: префиксные и на основе регулярных выражений. Есть еще несколько вариантов определения location
и они имеют различный приоритет. Понимание приоритетов необходимо корректной настройки Angie.
Типы location
в Angie.
Точный:
location = /test/.
Префиксный:
location /test/.
Префиксный без проверки регулярок:
location ^~ /test/.
Регулярное выражение без учета регистра:
location ~* /test/.
Регулярное выражение с учетом регистра:
location ~ /test/.
Именованный location:
location @fallback.
Общий алгоритм поиска location состоит из следующих шагов.
Поиск точного location (
=
).Если не нашли, ищем совпадения в префиксных location. Выигрывает самое длинное совпадение.
Если не нашли или найденный location позволяет проверку регулярных выражений (то есть он не
=
и не^~
), проверяем регулярные выражения по очереди до первого совпадения.При совпадении используем найденный, иначе используем неявный location на текущем уровне.
Внутри регулярных выражений выигрывает первое совпадение, то есть важен порядок указания location
в конфиге. В порядке приоритетов нет именованных location (@back)
, потому что в них попасть можно только в результате внутреннего перенаправления.
При выборе типов location нужно отдавать предпочтение префиксным location
, так, как они более предсказуемы и проще проверяются процессором выражений. Если всё‑таки необходимо использовать регулярные выражения, то стоит добавить якори (^
— начало строки, $
— конец строки) для более точного поиска совпадений.
Конфигурация типичного веб‑приложения включает в себя множество location
с одинаковой конфигурацией, посмотрим, как можно элегантно решить эту задачу.
Копирование конфигурации в location
Допустим, мы выбрали использование префиксных location
для статики. Скорее всего в результате получим примерно следующее:
location /images/ {
root /var/www;
add_header Cache-Control "max-age=31536000, immutable";
}
location /css/ {
root /var/www;
add_header Cache-Control "max-age=31536000, immutable";
}
location /js/ {
root /var/www;
add_header Cache-Control "max-age=31536000, immutable";
}
location /files/ {
root /var/www;
add_header Cache-Control "max-age=31536000, immutable";
}
Как видно, в каждом location
есть одинаковые директивы. Если root
имеет одинаковые значения в рамках всего server
, можно вынести эту директиву на уровень выше. Заголовок кэширования нужен только в статических location
, поэтому для удобства вынесем его в отдельный файл и подключим с помощью include
. Оптимизируем конфигурацию.
location /images/ {
include /etc/angie/static.conf;
}
location /css/ {
include /etc/angie/static.conf;
}
location /js/ {
include /etc/angie/static.conf;
}
location /files/ {
include /etc/angie/static.conf;
}
Теперь можно вспомнить, что мы используем Angie, что позволяет нам сделать комбинированный location
, сразу определив несколько location
в одном блоке. Результат получается более удобочитаемым:
location /files/
/css/
/js/
/images/ {
include /etc/angie/static.conf;
}
В этой конфигурации для изменения заголовка кэширования достаточно отредактировать файл /etc/angie/static.conf
и обновить конфигурацию. При этом файл с заголовком можно использовать и в других блоках server.
Таким образом, мы разобрали несколько способов разделения статических и динамических запросов в Angie, изучили типы location, а также их приоритеты.
Комментарии (7)
sirmax123
02.06.2025 15:24Если есть отличия от nginx то хорошо бы акцентировать на этом внимание
Nickmob Автор
02.06.2025 15:24Так и сделано, комбинированные location есть только в Angie, о чем прямо написано в тексте.
sirmax123
02.06.2025 15:24Я подумал что есть еще отличия, спасибо за ответ
Думаю ваша целевая аудитория знает как устроен nginx и как там настраивать location - повторять документацию nginx особого смысла вроде-бы нетNickmob Автор
02.06.2025 15:24Как показывает мой опыт, мало кто полностью понимает, как работает эта директива, несмотря на наличие документации.
php7
Можно еще так: