How can I make this try_files directive work?

a very common try_files line which can be applied on your condition is

you probably understand the first part, location / matches all locations, unless it’s matched by a more specific location, like location /test for example

Second condition is $uri/ which means if you didn’t find the first condition $uri try the URI as a directory, for example http://example.com/images/, ngixn will first check if a file called images exists then it wont find it, then goes to second check $uri/ and see if there’s a directory called images exists then it will try serving it.

EDIT: I forgot to mention that if you have index defined, nginx will try to check if the index exists inside this folder before
trying directory listing.

Third condition /test/index.html is considered a fall back option, (you need to use at least 2 options, one and a fall back), you can use as much as you can (never read of a constriction before), nginx will look for the file index.html inside the folder test and serve it if it exists.

If the third condition fails too, then nginx will serve the 404 error page.

Also there’s something called named locations, like this

You can call it with try_files like this

TIP: If you only have 1 condition you want to serve, like for example inside folder images you only want to either serve the image or go to 404 error, you can write a line like this

which means either serve the file or serve a 404 error, you can’t use only $uri by it self without =404 because you need to have a fallback option.
You can also choose which ever error code you want, like for example:

This will show a forbidden error if the image doesn’t exist, or if you use 500 it will show server error, etc ..

I’m trying to serve request to /blog subdirectory of a site with the php code, located in a folder outside document root directory. Here’s my host config:

And I get for requests like

wget -O — http://local.test.ru/blog/nonExisting

just a code of index.php file from /home/alex/www/test2/ folder.

However, this config:

gives me index.html file from /home/alex/www/test2/.
Please give me a clue — why? And how can I force NGINX to process /home/alex/www/test1/index.php instead?

asked Dec 6, 2013 at 14:49

1 gold badge4 silver badges8 bronze badges

Source: nginx/conf.d/app.conf from the debian-php-nginx stack in the docker-stack project

answered Jan 30, 2016 at 13:17

4 gold badges43 silver badges50 bronze badges

This is a long standing bug in nginx. But you can work around by using the root directive again. Kind of a hack, but at least it works.

45 gold badges398 silver badges571 bronze badges

answered Feb 15, 2014 at 2:46

4 gold badges49 silver badges55 bronze badges

In your case it should looks like this:

answered Aug 11, 2017 at 19:41

Введение

Nginx — один из самых популярных веб-серверов в мире. Он может успешно выдерживать высокую нагрузку с множеством одновременных подключений клиентов и функционировать как веб-сервер, почтовый сервер или обратный прокси-сервер.

В этом учебном модуле мы обсудим некоторые скрытые аспекты, определяющие, как Nginx обрабатывает запросы клиентов. Понимание этих идей поможет избежать догадок при проектировании сервера и блоков расположения, а также сделать обработку запросов более предсказуемой.

Конфигурации блока Nginx

Nginx логически разделяет на блоки конфигурации, обслуживающие разные виды контента, и размещает эти блоки в иерархической структуре. При каждом поступлении клиентского запроса Nginx определяет, какие блоки конфигурации следует использовать для его обработки. Об этом процессе мы и расскажем в этом учебном модуле.

В первую очередь мы расскажем о блоках server и location.

Блок location располагается внутри блока server и определяет, как Nginx будет обрабатывать запросы различных ресурсов и URI для родительского сервера. Администратор, использующий эти блоки, может разделить пространство URI любым удобным способом. Это чрезвычайно гибкая модель.

Как Nginx решает, какой серверный блок будет обрабатывать запрос

Поскольку Nginx разрешает администратору определять несколько серверных блоков, работающих как отдельные экземпляры виртуального веб-сервера, ему требуется процедура, определяющая, какие серверные блоки будут использоваться для выполнения запроса.

Для этого используется фиксированная система проверок, служащих для подбора оптимального совпадения. Главные директивы серверного блока, которые учитывает Nginx в этом процессе — директивы listen и server_name.

Синтаксический анализ директивы “listen” для поиска возможных совпадений

Директиву listen можно задать следующим образом:

  • Одиночный порт, который прослушивает каждый интерфейс этого порта.
  • Путь к сокету Unix.

Последняя опция обычно влияет только на передачу запросов между разными серверами.

Вначале Nginx попробует выбрать серверный блок, на который будет отправлен запрос, на основе специфики директивы listen, используя следующие правила:

  • Блок без директивы listen использует значение 0.0.0.0:80.
  • Если будет найдено одно наиболее точное совпадение, запрос будет обработан с помощью данного серверного блока. Если будет найдено несколько серверных блоков с одинаковым уровнем соответствия, Nginx начнет оценку директивы server_name каждого серверного блока.

В случае равного уровня соответствия нескольких серверных блоков следующим шагом будет проверка директивы server_name.

Проверка директивы “server_name” для выбора совпадения

Nginx пытается подобрать наилучшее значение на основе директивы server_name в каждом из серверных блоков, которые являются наилучшим соответствием. Nginx оценивает их по следующей формуле:

  • Nginx сначала попытается найти серверный блок со значением server_name, точно соответствующим значению в заголовке запроса “Host”. Если такой элемент найден, для обслуживания запроса будет использован соответствующий блок. Если найдется несколько точных совпадений, используется первый вариант.
  • Если точных совпадений найдено не будет, Nginx будет пытаться найти серверный блок с директивой server_name, соответствующей первому подстановочному символу (обозначается символом * в начале названия в конфигурации). Если такой блок будет найден, он будет использоваться для обслуживания запроса. Если будут найдены несколько совпадений, для обслуживания запроса будет использоваться самое длинное из них.
  • Если совпадений с начальным подстановочным символом не будет, Nginx начнет искать серверный блок со значением server_name, соответствующим конечному подстановочному символу (указывается именем сервера с символом * в конфигурации). Если такой блок будет найден, он будет использоваться для обслуживания запроса. Если будут найдены несколько совпадений, для обслуживания запроса будет использоваться самое длинное из них.
  • Если совпадений с использованием конечного подстановочного символа найдено не будет, Nginx будет оценивать серверные блоки, определяющие server_name, с помощью регулярных выражений (обозначаются символом ~ перед названием). Для выполнения запроса будет использоваться первая директива server_name с регулярным выражением, соответствующим заголовку “Host”.
Читайте также:  Купить домен | Зарегистрировать доменное имя по выгодной цене в

Примеры

Если будет определена директива server_name, которая точно соответствует значению заголовка “Host”, для обработки запроса будет выбран соответствующий серверный блок.

В этом примере, если для запроса задать заголовку “Host” значение “host1.example.com”, будет выбран второй сервер:

Если точного совпадения найдено не будет, Nginx проверяет наличие параметра server_name с подходящим начальным подстановочным символом. Для выполнения запроса будет выбрано самое длинное совпадение, начинающееся с подстановочного символа.

В этом примере, если заголовок “Host” запроса будет иметь значение “www.example.org”, будет выбран второй серверный блок:

Если не будет найдено совпадения с начальным подстановочным символом, Nginx проверит наличие совпадения с подстановочным символом в конце выражения. На этом шаге для обслуживания запроса выбирается наиболее длинное совпадение, заканчивающееся подстановочным символом.

Например, если заголовок “Host” запроса имеет значение “www.example.com”, будет выбран третий серверный блок:

Если совпадений с подстановочными символами найдено не будет, Nginx попытается подобрать директивы server_name, использующие регулярные выражения. Первое совпадающее регулярное выражение будет выбрано для реагирования на запрос.

Например, если заголовок “Host” будет иметь значение “www.example.com”, для выполнения запроса будет выбран второй серверный блок:

Совпадающие блоки расположения

Аналогично процессу, который Nginx использует для выбора серверного блока для обработки запроса, Nginx также имеет стабильный алгоритм для определения блока расположения сервера, который будет использоваться для обработки запросов.

Синтаксис блока расположения

Блоки расположения обычно принимают следующую форму:

location_match выше определяет, что Nginx следует проверять в отношении URI запроса. Наличие или отсутствие модификатора в примере выше влияет на то, как Nginx пытается подобрать соответствие блока расположения. Далее перечислены модификаторы, используемые для интерпретации блока расположения:

  • (нет): если модификаторов нет, расположение определяется как соответствие префикса. Это означает, что расположение будет сверяться с началом URI запроса для определения совпадения.
  • =: если используется знак равенства, блок будет считаться совпадающим, если URI запроса точно соответствует указанному расположению.
  • ~: знак тильды означает, что это расположение будет интерпретироваться как совпадение с регулярным выражением с учетом регистра.
  • ~*: знак тильды со звездочкой означают, что блок расположения будет интерпретироваться как совпадение с регулярным выражением без учета регистра.
  • ^~: знак елочки с тильдой означают, что если этот блок будет выбран как лучшее соответствие без регулярных выражений, сопоставление по регулярным выражением проводиться не будет.

Примеры, демонстрирующие синтаксис блока расположения

В качестве примера соответствия префиксов можно выбрать следующий блок расположения для реагирования на URI запроса вида /site, /site/page1/index.html или /site/index.html:

Как пример точного соответствия URI запроса, этот блок всегда будет использоваться для ответа на URI запроса вида /page1. Он не будет использоваться для ответа на URI запроса /page1/index.html. Помните, что если выбран этот блок, и если запрос выполняется с использованием страницы индекса, произойдет внутренняя переадресация на другое расположение, которое фактически и будет обрабатывать запрос:

Как пример расположения, которое следует интерпретировать как регулярное выражение с учетом регистра, этот блок можно использовать для обработки запросов /tortoise.jpg, но не запросов /FLOWER.PNG:

Ниже показан похожий блок, поддерживающий сопоставление без учета регистра. Этот блок может обрабатывать как запросы /tortoise.jpg, так и запросы /FLOWER.PNG:

Наконец, этот блок не даст выполнять сопоставление с регулярными выражениями, если будет признан лучшим совпадением без регулярного выражения. Он сможет обрабатывать запросы /costumes/ninja.html:

Как видите, модификаторы показывают, как следует интерпретировать блок расположения. Однако это не говорит нам, какой алгоритм Nginx использует для определения блока расположения, в который будет отправлен запрос. Этот вопрос мы рассмотрим далее.

Как Nginx выбирает расположение для обработки запросов

Nginx выбирает расположение, которое будет использоваться для обработки запроса аналогично выбору серверного блока. Он выполняет процесс, определяющий наилучший блок расположения для любого заданного запроса. Понимание этого процесса очень важно для возможности надежной и точной настройки Nginx.

Учитывая описанные выше типы деклараций расположения, Nginx оценивает возможные контексты расположения, сравнивая URI запроса с каждым расположением. Для этого используется следующий алгоритм:

  • Для начала Nginx проверяет все совпадения расположения на базе префиксов (все типы расположений без регулярных выражений). Каждое расположение сверяется с полным URI запроса.
  • Во-первых, Nginx ищет точное совпадение. Если блок расположения, использующий модификатор =, будет точно соответствовать URI запроса, этот блок расположения сразу же будет выбран для обслуживания запроса.
  • Если точное соответствие (с модификатором =) блока расположения найдено не будет, Nginx перейдет к оценке неточных префиксов. Он определит самое длинное совпадающее расположение префикса для указанного URI запроса, которое будет оценено следующим образом:
    Если совпадающее расположение с самым длинным префиксом имеет модификатор ^~, Nginx немедленно прекращает поиск и выбирает это расположение для обслуживания запроса.Если совпадающее расположение с самым длинным префиксом не имеет модификатор ^~, Nginx временно сохраняет его, чтобы можно было сместить фокус поиска.
  • Если совпадающее расположение с самым длинным префиксом имеет модификатор ^~, Nginx немедленно прекращает поиск и выбирает это расположение для обслуживания запроса.
  • Если совпадающее расположение с самым длинным префиксом не имеет модификатор ^~, Nginx временно сохраняет его, чтобы можно было сместить фокус поиска.
  • После определения и сохранения совпадающего расположения с самым длинным префиксом Nginx переходит к оценке расположений с регулярными выражениями (с учетом регистра и без учета регистра). Если расположения с регулярными выражениями будут найдены внутри совпадающего расположения с самым длинным префиксом, Nginx переместит их наверх списка расположений с регулярными выражениями для проверки. Затем Nginx попытается подбирать расположения регулярных выражений последовательно. Первое регулярное выражение, соответствующее URI запроса, будет сразу же выбрано для обслуживания запроса.
  • Если не будет найдено никаких расположений регулярных выражений, соответствующих URI запроса, для обслуживания запроса будет выбрано ранее сохраненное расположение префикса.

Важно понимать, что по умолчанию Nginx будет отдавать совпадениям регулярных выражений приоритет перед совпадениями префиксов. Однако он вначале оценивает расположения префиксов, позволяя администратору переопределить этот приоритет, используя модификаторы = и ^~ при определении расположения.

Читайте также:  Хостинг для сайтов на CMS Joomla

Также важно отметить, что хотя расположения префиксов обычно определяются на основе самого длинного и точного совпадения, оценка регулярных выражений останавливается при обнаружении первого совпадения. Это означает, что расположение в конфигурации важно для расположения регулярных выражений.

Наконец, важно понимать, что совпадения регулярных выражений с самым длинным совпадением префикса будут иметь больший приоритет при оценке регулярных выражений Nginx. Они будут оцениваться по порядку до начала оценки любых других совпадений регулярных выражений. Максим Дунин, разработчик Nginx, дающий очень много полезных советов, объясняет в этом сообщении принципы работы данной части алгоритма выбора.

Когда оценка блока расположения переходит к другим расположениям?

Обычно, когда для обслуживания запроса выбирается блок расположения, запрос полностью обрабатывается в этом контексте, начиная с этого момента. Обработка запроса определяется только выбранным расположением и унаследованными директивами без вмешательства других родственных блоков расположения.

Хотя это общее правило, позволяющее прогнозируемо проектировать блоки расположения, важно понимать, что иногда определенные директивы в выбранном расположении могут активировать новый поиск расположения. Исключения из правила использования только одного блока расположения могут влиять на фактический процесс обработки запроса и не соответствовать вашим ожиданиям при проектировании блоков расположения.

Вот некоторые директивы, которые могут активировать подобную внутреннюю переадресацию:

  • index
  • try_files
  • rewrite
  • error_page

Давайте вкратце рассмотрим их.

Директива index всегда вызывает внутреннюю переадресацию, если используется для обработки запроса. Точные совпадения расположения часто используются для ускорения процесса выбора с немедленным завершением алгоритма. Однако, если точное совпадение расположения представляет собой каталог, есть вероятность, что запрос будет переадресован для фактической обработки в другое расположение.

В этом примере первому расположению соответствует URI запроса /exact, но для обработки запроса директива index, унаследованная блоком, активирует внутреннюю переадресацию во второй блок:

Если в примере выше вы захотите ограничить исполнение первым блоком, вам нужно будет подобрать другой метод выполнения запроса каталога. Например, вы можете задать недопустимый index этого блока и включить autoindex:

Этот способ позволит предотвратить переключение контекста index, но в большинстве конфигураций он не будет полезен. Более точное совпадение каталогов может помочь в таких случаях как перезапись запроса (в результате чего также выполняется новый поиск расположения).

Также расположение обработки может переоцениваться при использовании директивы try_files. Эта директива предписывает Nginx проверить существование набора файлов или каталогов с определенным именем. Последним параметром может быть URI, на который Nginx осуществляет внутреннюю переадресацию.

Рассмотрим следующую конфигурацию:

В примере выше, если мы делаем запрос /blahblah, запрос получит первое расположение. Оно попытается найти файл с именем blahblah в каталоге /var/www/main. Если это не получится сделать, будет выполнен поиск файла с именем blahblah.html. Затем будет выполнен поиск каталога blahblah/ в каталоге /var/www/main. Если все эти попытки закончатся неудачно, будет выполнена переадресация на /fallback/index.html. В этом случае будет активирован другой поиск расположения, который будет перехвачен вторым блоком расположения. Он выдаст файл /var/www/another/fallback/index.html.

Также смена блока расположения возможна при использовании директивы rewrite. При использовании параметра last с директивой rewrite или при ее использовании без каких-либо параметров Nginx выполняет поиск нового подходящего расположения на основе результатов перезаписи.

Например, если мы изменим последний пример и включим в него директиву rewrite, мы увидим, что запрос будет иногда передаваться во второе расположение без использования директивы try_files:

В примере выше запрос /rewriteme/hello будет первоначально обработан первым блоком расположения. Он будет перезаписан в /hello, и будет выполнен поиск расположения. В этом случае совпадением опять будет первое расположение, и будет выполнена обычная обработка try_files, возможно с возвратом к /fallback/index.html, если ничего не будет найдено (посредством внутренней переадресации try_files, как описано выше).

Однако в случае запроса /rewriteme/fallback/hello первый блок опять будет соответствовать. В этом случае снова будет применена перезапись, в данном случае на /fallback/hello. Затем запрос будет выполнен вторым блоком расположения.

Похожая ситуация происходит с директивой return при отправке кодов состояния 301 или 302. В данном случае разница заключается в том, чтобы обработать совершенно новый запрос в форме внешней видимой переадресации. Такая же ситуация может возникнуть с директивой rewrite при использовании флагов redirect или permanent. Однако эти поиски расположения не должны быть неожиданными, поскольку внешняя видимая переадресация всегда приводит к созданию нового запроса.

Директива error_page может вызвать внутреннюю переадресацию, аналогичную созданной try_files. Эта директива используется, чтобы определить, что должно происходить при получении определенных кодов состояния. Она практически никогда не выполняется вместе с try_files, потому что обрабатывает весь жизненный цикл запроса.

Рассмотрим следующий пример:

Каждый запрос, кроме начинающихся с /another, будет обрабатываться первым блоком, который будет выводить файлы из /var/www/main. Однако, если файл не будет найден (статус 404), будет выполнена внутренняя переадресация на /another/whoops.html, в результате чего будет активирован новый поиск расположения, который попадет на второй блок. Файл будет выводиться из /var/www/another/whoops.html.

Как видите, понимание обстоятельств, в которых Nginx активирует новый поиск расположения, может помочь прогнозировать поведение, которое вы будете наблюдать при отправке запросов.

Заключение

Понимание способов обработки запросов клиентов в Nginx может значительно упростить работу администратора. Вы сможете понимать, какой серверный блок будет выбирать Nginx в ответ на запрос каждого клиента. Также вы поймете, как определить выбираемый блок расположения на основе URI запроса. Понимание того, как Nginx выбирает разные блоки, позволит вам отслеживать применяемые Nginx контексты для обслуживания каждого запроса.

Introduction

Nginx is one of the most popular web servers in the world. It can successfully handle high loads with many concurrent client connections, and can function as a web server, a mail server, or a reverse proxy server.

How Nginx Decides Which Server Block Will Handle a Request

The listen directive can be set to:

  • An IP address/port combo.
  • A lone port which will listen to every interface on that port.
  • The path to a Unix socket.

The last option will generally only have implications when passing requests between different servers.

Parsing the server_name Directive to Choose a Match

Next, to further evaluate requests that have equally specific listen directives, Nginx checks the request’s Host header. This value holds the domain or IP address that the client was actually trying to reach.

Examples

In this example, if the Host header of the request was set to host1.example.com, the second server would be selected:

If no exact match is found, Nginx then checks to see if there is a server_name with a starting wildcard that fits. The longest match beginning with a wildcard will be selected to fulfill the request.

Читайте также:  Легко экспортируйте сертификаты в PFX с помощью CryptoPro: подробное руководство

If no match is found with a starting wildcard, Nginx will then see if a match exists using a wildcard at the end of the expression. At this point, the longest match ending with a wildcard will be selected to serve the request.

If no wildcard matches can be found, Nginx will then move on to attempting to match server_name directives that use regular expressions. The first matching regular expression will be selected to respond to the request.

If none of the above steps are able to satisfy the request, then the request will be passed to the default server for the matching IP address and port.

Matching Location Blocks

  • (none): If no modifiers are present, the location is interpreted as a prefix match. This means that the location given will be matched against the beginning of the request URI to determine a match.
  • ~: If a tilde modifier is present, this location will be interpreted as a case-sensitive regular expression match.

Examples Demonstrating Location Block Syntax

  • Nginx begins by checking all prefix-based location matches (all location types not involving a regular expression). It checks each location against the complete request URI.
  • If the longest matching prefix location has the ^~ modifier, then Nginx will immediately end its search and select this location to serve the request.
  • If the longest matching prefix location does not use the ^~ modifier, the match is stored by Nginx for the moment so that the focus of the search can be shifted.
  • After the longest matching prefix location is determined and stored, Nginx moves on to evaluating the regular expression locations (both case sensitive and insensitive). If there are any regular expression locations within the longest matching prefix location, Nginx will move those to the top of its list of regex locations to check. Nginx then tries to match against the regular expression locations sequentially. The first regular expression location that matches the request URI is immediately selected to serve the request.
  • If no regular expression locations are found that match the request URI, the previously stored prefix location is selected to serve the request.

It is also important to note that, while prefix locations generally select based on the longest, most specific match, regular expression evaluation is stopped when the first matching location is found. This means that positioning within the configuration has vast implications for regular expression locations.

Finally, it it is important to understand that regular expression matches within the longest prefix match will “jump the line” when Nginx evaluates regex locations. These will be evaluated, in order, before any of the other regular expression matches are considered. Maxim Dounin, an incredibly helpful Nginx developer, explains in this post this portion of the selection algorithm.

When Does Location Block Evaluation Jump to Other Locations?

Some directives that can lead to this type of internal redirect are:

Let’s go over these briefly.

The index directive always leads to an internal redirect if it is used to handle the request. Exact location matches are often used to speed up the selection process by immediately ending the execution of the algorithm. However, if you make an exact location match that is a directory, there is a good chance that the request will be redirected to a different location for actual processing.

This is one way of preventing an index from switching contexts, but it’s probably not useful for most configurations. Mostly an exact match on directories can be helpful for things like rewriting the request (which also results in a new location search).

Another instance where the processing location may be reevaluated is with the try_files directive. This directive tells Nginx to check for the existence of a named set of files or directories. The last parameter can be a URI that Nginx will make an internal redirect to.

For example, if we modify the last example to include a rewrite, we can see that the request is sometimes passed directly to the second location without relying on the try_files directive:

A related situation happens with the return directive when sending the 301 or 302 status codes. The difference in this case is that it results in an entirely new request in the form of an externally visible redirect. This same situation can occur with the rewrite directive when using the redirect or permanent flags. However, these location searches shouldn’t be unexpected, since externally visible redirects always result in a new request.

The error_page directive can lead to an internal redirect similar to that created by try_files. This directive is used to define what should happen when certain status codes are encountered. This will likely never be executed if try_files is set, since that directive handles the entire life cycle of a request.

Consider this example:

As you can see, understanding the circumstances in which Nginx triggers a new location search can help to predict the behavior you will see when making requests.

Conclusion

The examples in this guide were tested on an Ubuntu 22.04 server, but should be applicable to most Nginx installations, given that it deals mostly within a standardized configuration file. Directories and paths may differ slightly.

In this tutorial, you will learn about syntax errors that may occur in your Nginx configuration file, how to check for them, and how to correct them.

Please note that you can always refer to the Nginx error log to view a running list:

This tutorial will cover how to break down and understand the parts of an Nginx error message later on.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If there are errors, you will receive a message that identifies the exact file and line of code where the error is occurring, and the specific syntax issue you need to resolve.

Оцените статью
Хостинги