In this section, we will discuss how to configure the Nginx Plus and Nginx open source to serve static content.
- Introduction
- Introduction
- Root внутри секции location
- Несколько директив index
- Использование if
- Имя сервера
- Проверка наличия файла
- Передача запросов на PHP
- Путь FastCGI
- Перезапись (rewrite)
- Отсутствующий http://
- Проксирование
- Самое главное
- Trying Several Options
- Регулярные выражения в location Nginx
- За счет rewrite
- Перенаправление за счет try_files
- Root Directory and Index Files
- Переход в другой location
- Nginx location, примеры использования и принципу выбора location
- За счет error_page
- General Rules to Follow Regarding Contexts
- Apply Directives in the Highest Context Available
- Use Multiple Sibling Contexts Instead of If Logic for Processing
- Root, location and try_files directives
- root directive
- Location Directive
- try_files directive
- Other Contexts
- The Upstream Context
- The If Context
- The Limit_except Context
- The Core Contexts
- The Main Context
- The Events Context
- The HTTP Context
- The Server Context
- The Location Context
- How NGINX choose a location block
- NGINX location directive syntax
- Практический пример поясняющие использование Nginx location
- Matching Location Blocks
- Location Block Syntax
- Examples Demonstrating Location Block Syntax
- How Nginx Chooses Which Location to Use to Handle Requests
- When Does Location Block Evaluation Jump to Other Locations?
- Optimizing Performance for Serving Content
- Принципы обработки location и директивы listen
- Understanding Nginx Configuration Contexts
- How Nginx Decides Which Server Block Will Handle a Request
- Parsing the listen Directive to Find Possible Matches
- Parsing the server_name Directive to Choose a Match
- Examples
- NGINX location block examples
- 1. NGINX location matching all requests
- 2. NGINX location matching exact URL
- 3. NGINX location block for a directory
- 4. NGINX location RegEx Example
- 5. NGINX location block for image/css/js file types
- 6. NGINX location RegEx Case Sensitive Match
- 7. NGINX location RegEx Case Insensitive Match Example
- Conclusion
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.
Introduction
Nginx is a high performance web server that is responsible for handling the load of some of the largest sites on the internet. It is especially good at handling many concurrent connections and excels at forwarding or serving static content. In this guide, we will focus on discussing the structure of an Nginx configuration file along with some guidelines on how to design your files.
A secure server is one that allows only as much as what is needed. Ideally, we would build a server based on a minimal system by enabling additional features individually. Doing with a minimal configuration is also helpful in debugging. If the error is not available in the minimal system, features are added individually and the search for the error goes on.
Here is the minimal configuration needed to run nginx:
Nginx location — структура в конфигурационном файле Nginx определяющая к URl и запросам какого вида будут применяться описанные правила.
Директива location всегда задается внутри блока server конфигурационного файла Nginx. С location используют регулярные выражения, при этом выполняются действия заданные для блока для которого совпадение с маской самое узкое.
Т.е. под location / будут попадать все файлы, обрабатываемые сервером, под location ~ .php будут попадать только скрипты с расширением .php, опции для корня обрабатываться не будут. Ниже основные случаи будут рассмотрены подробно.
The approach with
try_files $uri $uri/index.html index.html;
is bad, as mentioned in a comment above, because it returns index.html for pages which should not exist on your site (any possible $uri will end up in that).
Also, as mentioned in an answer above, there is an internal redirect in the last argument of try_files.
location = / { index index.html;
is also bad, since index makes an internal redirect too. In case you want that, you should be able to handle that in a specific location. Create e.g.
location = /index.html {as was proposed here. But then you will have a working link http://example.org/index.html, which may be not desired. Another variant, which I use, is:
root /www/my-root;
# http://example.org
# = means exact location
location = / { try_files /index.html =404;
}
# disable http://example.org/index as a duplicate content
location = /index { return 404; }
# This is a general location.
# (e.g. http://example.org/contacts <- contacts.html)
location / { # use fastcgi or whatever you need here # return 404 if doesn't exist try_files $uri.html =404;
}error_log /var/log/nginx/debug.log debug;and see there all internal redirects etc.
I tried to set a location similar as «Apache Alias» with Nginx but I don’t able to process PHP script in this folder.
Here is my folder structure (for Dev environment):
/var/www
+- dev/public/ <-- This is my normal Web root : "/"
| +- assets/
| | +- app.css
| | +- app.js
| |
| +- index.php
| +- favicon.png
|
+- cut/public/ <-- This must like an "Apache Alias" : "/cut" +- assets/ | +- app.css | +- app.js | +- index.php +- other_other_file.php (why not)I’ve tried different solutions but none of them are working.
Here is my best Nginx configuration :
server { listen 80; server_name _; root /var/www/dev/public/; index index.php index.html; autoindex on; # Logs rewrite_log on; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; # Serving files location / { try_files $uri $uri/ @php; } location /cut { root /var/www/cut/public; try_files $uri $uri/ @php; } # PHP location @php { rewrite ^(.*)/?$ /index.php$is_args$args last; } location ~* \.php(/|$) { fastcgi_pass php:9000; fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
}With this one, all the content of my cut/public/ folder is redirected to the dev/public/index.php and interpreted (cause of try_file, I presume).
That is why your help would be welcome.
server { listen 80; server_name _; root /var/www/dev/public/; index index.php index.html; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; location ^~ /cut { rewrite ^/cut/?(.*)$ /cut/public/$1 last; } location ^~ /cut/public { root /var/www/; try_files $uri $uri/ /cut/index.php$is_args$args; location ~* \.php(/|$) { fastcgi_pass php:9000; fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } location / { try_files $uri $uri/ /index.php$is_args$args; } location ~* \.php(/|$) { fastcgi_pass php:9000; fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
}server { index index.html index.htm; server_name test.example.com; location / { root /web/test.example.com/www; } location /static { root /web/test.example.com/static; }
}In this example going to test.example.com/ would bring the index file in /web/test.example.com/www
and going to test.example.com/static would bring the index file in /web/test.example.com/static

9 gold badges51 silver badges107 bronze badges
asked Jul 19, 2012 at 22:35
You need to use the alias directive for location /static:
server { index index.html; server_name test.example.com; root /web/test.example.com/www; location /static/ { alias /web/test.example.com/static/; }
}The nginx wiki explains the difference between root and alias better than I can:
Note that it may look similar to the root directive at first sight, but the document root doesn’t change, just the file system path used for the request. The location part of the request is dropped in the request Nginx issues.
Note that root and alias handle trailing slashes differently.
answered Jul 20, 2012 at 6:22
3 gold badges15 silver badges21 bronze badges
The Location directive system is
Like you want to forward all request which start /static and your data present in /var/www/static
So a simple method is separated last folder from full path , that means
Full path : /var/www/static
Last Path : /static and First path : /var/www
location <lastPath> { root <FirstPath>;
}So lets see what you did mistake and what is your solutions
Your Mistake :
location /static { root /web/test.example.com/static;
}Your Solutions :
location /static { root /web/test.example.com;
}
15 gold badges85 silver badges122 bronze badges
answered May 4, 2015 at 19:36

1 gold badge10 silver badges17 bronze badges
server { index index.html index.htm; server_name test.example.com; location / { root /web/test.example.com/www; } location /static { root /web/test.example.com; }
}1 gold badge33 silver badges29 bronze badges
answered Jul 20, 2012 at 16:17
4 gold badges45 silver badges49 bronze badges
A little more elaborate example.
Setup: You have a website at example.com and you have a web app at example.com/webapp
...
server { listen 443 ssl; server_name example.com; root /usr/share/nginx/html/website_dir; index index.html index.htm; try_files $uri $uri/ /index.html; location /webapp/ { alias /usr/share/nginx/html/webapp_dir/; index index.html index.htm; try_files $uri $uri/ /webapp/index.html; }
}
...I’ve named webapp_dir and website_dir on purpose. If you have matching names and folders you can use the root directive.
This setup works and is tested with Docker.
NB!!! Be careful with the slashes. Put them exactly as in the example.
answered Sep 15, 2020 at 21:24
If you use this, I will suggest you set up this command too.
location /static/ { proxy_set_header Host $host/static; // if you change the directory and the browser can't find your path alias /web/test.example.com/static/;
}answered Aug 2, 2021 at 18:49
If you want to check two different directories for the same URI use this config:
server {
... root /var/www/my-site/public/;
... index index.php index.html index.htm;
... location / { root /var/www/old-site/dist/; try_files $uri $uri/ /index.php$is_args$args; }
...
}If Nginx couldn’t find file in /var/www/old-site/dist/ directory, then it will try file in /var/www/my-site/public/ directory, but as we said to Nginx to try files with $uri $uri/ /index.php$is_args$args patterns, so Nginx will try /index.php$is_args$args in /var/www/my-site/public/ directory. not $uri
answered Aug 28, 2022 at 12:44

Наткнуться на подводные камни в конфигурации и работе веб-сервера очень легко. Но трудно понять причину некорректной или не всегда корректной/ошибочной работы, если все правила соблюдаются.
Root внутри секции location
Нет ничего плохого в размещении root-директории внутри location. Но если location не соответствует, то у нее не будет доступа к корневому каталогу. Правильнее делать так:
server { server_name www.somesite.com; root /var/www/nginx-default/; location / { } location /foo { } location /bar { }
}Несколько директив index
Не нужно плодить большое количество директив index. Пропишите ее один раз в блоке http:
http { index index.php index.htm index.html; server { server_name www.somesite.com; location / { } } server { server_name somesite.com; location / { } location /foo { } }
}Использование if
Вы же в курсе, что if = зло? При использовании директивы нужно быть осторожным, ошибиться несложно. Так что по возможности избегайте использования if.
Имя сервера
Предположим, ваш сайт лежит на домене somesite.com и вы перенаправляете на него пользователей, которые идут на www.somesite.com:
server { server_name somesite.com *.somesite.com; if ($host ~* ^www\.(.+)) { set $raw_domain $1; rewrite ^/(.*)$ $raw_domain/$1 permanent; } }
}Здесь несколько проблем. Главная — if. Вне зависимости от запроса хоста (с www или без), Nginx все равно проверяет if. Для каждого запроса. Взамен можно сделать так:
server { server_name www.somesite.com; return 301 $scheme://somesite.com$request_uri;}
server { server_name somesite.com; }Проверка наличия файла
Не используйте if для проверки наличия файла:
server { root /var/www/somesite.com; location / { if (!-f $request_filename) { break; } }
}Взамен у Nginx есть директива try_files:
server { root /var/www/somesite.com; location / { try_files $uri $uri/ /index.html; }
}Примечательно, что директиву также можно использовать для защиты веб-сервера от несанкционированного доступа.
Передача запросов на PHP
Если Nginx перенаправляет все запросы, заканчивающиеся на .php, напрямую на интерпретатор PHP, то для злоумышленников открываются возможности для выполнения стороннего кода. PHP по умолчанию пытается догадаться, куда должен вести неправильный запрос. Так что в первую очередь необходимо подправить php.ini, указав:
cgi.fix_pathinfo=0
Обратите внимание на правильную конфигурацию Nginx:
# Перенаправляет запросы только для указанных файлов
location ~* (file_a|file_b|file_c)\.php$ { fastcgi_pass backend; }
location /uploaddir { location ~ \.php$ {return 403;} }
location ~* \.php$ { try_files $uri =404; fastcgi_pass backend; }
location ~* \.php$ { location ~ \..*/.*\.php$ {return 404;} fastcgi_pass backend; }Путь FastCGI
Неправильное указание путей размещения скриптов FastCGI часть приводит к ошибке “Primary script unknown”, которая легко решается.
Перезапись (rewrite)
Используйте переменную $request_uri для изменения URI запроса:
rewrite ^ http://somesite.com$request_uri? permanent; return 301 http://somesite.com$request_uri;
Отсутствующий http://
Добавить отсутствующий http:// очень просто:
rewrite ^ http://somesite.com permanent;
Проксирование
Не перенаправляйте все запросы на PHP в таком виде:
server { server_name _; root /var/www/site; location / { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/tmp/phpcgi.socket; }
}Используйте все те же директиву try_files:
server { server_name _; root /var/www/site; location / { try_files $uri $uri/ @proxy; } location @proxy { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/tmp/phpcgi.socket; }
}server { server_name _; root /var/www/site; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/tmp/phpcgi.socket; }
}Самое главное
Основная причина ошибочной работы системы (не только Nginx) — бездумный копипаст. Проверяйте конфиги, тестируйте приложение перед выкаткой, читайте документацию.
Trying Several Options
The file is defined in the form of the URI, which is processed using the root or alias directives set in the context of the current location or virtual server. In this case, if the file corresponding to the original URI doesn’t exist, NGINX makes an internal redirect to the URI specified by the last parameter, returning /www/data/images/default.gif.
The last parameter can also be a status code which is directly preceded by the equals sign or the name of a location. In the below example, a 404 error is returned if none of the parameters to the try_files directive resolve to an existing file or directory.
Регулярные выражения в location Nginx
- = строковые совпадения, если совпадение с шаблоном обнаружено дальнейшая проверка заканчивается
- ~ тильда в начале означает, что регистр будет учитываться
- ~ регулярные вырадения без учета регистра
- ^~ приоритетное строковое значение, чтобы применились опции требуется совпадение начала выражения — если это каталог, то директивы текущего location будут распространяться на все файлы в нем
За счет rewrite
Запрос к example.com/newrequest/someurl будет обрабатываться location / без какой-либо переадресации
server_name example.com; root /home/sites/example.com; location / { rewrite ^/newrequest/(.\*)$ /$1; try_files $uri $uri.html $uri/ /none/index.html; }return работает также, но используется обычно для переадресации на URL, а не в другой location
Его добавляют, когда нужно перенаправить пользователя на другой домен или другую версию сайта (например без www или с https)
Перенаправление за счет try_files
server_name example.com; root /home/sites/example.com; location / { try_files $uri $uri.html $uri/ /none/index.html; }
location /none { root /var/sites/new; }При поступлении запроса к example.com/request Nginx первым делом увидит $uri и поппытается найти location request.
Такого нет, далее следует поиск request.html и каталога request. Если таких нет, то запрос переадресуется в резервный location на страницу /none/index.html
Веб-сервер выдаст пользователю содержимое /var/sites/new/none/index.html
Root Directory and Index Files
If a request suffix with a slash, NGINX treats it as a request for a directory and tries to find an index file in the directory. The index directive specifies the name of the index file (the default value is index.html). To continue with the example, if the request URI is /images/some/path/, NGINX delivers the file /www/data/images/some/path/index.html if it exists. If it does not then by default NGINX returns HTTP code 404 (Not Found). To configure NGINX to return an automatically generated directory listing instead, add the «on» parameter to the auto index directive:
We can list more than one filename in the index directive. NGINX finds for files in the specified order and returns the first one it finds.
The $geo variable used here is a custom variable set through the geo directive. The value of the variable depends on the IP address of the client.
In the above example, if the URI in a request is /path/, and /data/path/index.html does not exist but /data/path/index.php does, the internal redirect to /path/index.php is mapped to the second location. As a result, the request is proxied.
Переход в другой location
Перенаправление в другой блок выполняется за счет одной из приведенных ниже директив:
try_files rewrite error_pageNginx location, примеры использования и принципу выбора location
Веб-сервером Nginx location выбирается сравнивая URI поступившего запроса с обозначением location
1) с полным URI сравниваются все выражения, не включающие регулярные выражения
2) сначала сверяются все блоки с =
3) если совпадений нет проверяется ^~ и сразу задействуется самый длинный из них
4) не найдя таких Nginx ищет опять же самое длинное совпадение и резервирует результат поиска
5) проверка с учетом регулярных выражений — выбирается первое выражение среди подходящих под самый длинный префикс
6) при отсутствии результата используется блок, зарезервированный на шаге 4
Изменить эту логику и заставить какой-то блок обрабатываться вперед остальных проще всего используя = или ^~
За счет error_page
Это скорее не редирект, а способ задания собственных страниц ошибок. Перенаправление будет происходить каждый раз когда не найдена запрашиваемая страница
location / { error_page 404 /somefolder/errorpage.html;
}General Rules to Follow Regarding Contexts
Now that you have an idea of the common contexts that you are likely to encounter when exploring Nginx configurations, we can discuss some best practices to use when dealing with Nginx contexts.
Apply Directives in the Highest Context Available
Many directives are valid in more than one context. For instance, there are quite a few directives that can be placed in the http, server, or location context. This gives us flexibility in setting these directives.
As a general rule, it is usually best to declare directives in the highest context to which they are applicable, and overriding them in lower contexts as necessary. This is possible because of the inheritance model that Nginx implements. There are many reasons to use this strategy.
First of all, declaring at a high level allows you to avoid unnecessary repetition between sibling contexts. For instance, in the example below, each of the locations is declaring the same document root:
http { server { location / { root /var/www/html; . . . } location /another { root /var/www/html; . . . } }
}http { root /var/www/html; server { location / { . . . } location /another { . . . } }
}Most of the time, the server level will be most appropriate, but declaring at the higher level has its advantages. This not only allows you to set the directive in fewer places, it also allows you to cascade the default value down to all of the child elements, preventing situations where you run into an error by forgetting a directive at a lower level. This can be a major issue with long configurations. Declaring at higher levels provides you with a good default.
Use Multiple Sibling Contexts Instead of If Logic for Processing
The result is usually more readable and also has the added benefit of being more performant. Correct requests undergo no additional processing and, in many cases, incorrect requests can get by with a redirect rather than a rewrite, which should execute with lower overhead.
Root, location and try_files directives
root directive
The root directive is used to set the root directory for requests, allowing nginx to map the incoming request onto the file system.
It allows nginx to return server content according to the request:
Location Directive
The location directive is used to set the configuration depending on the requested URI (Uniform Resource Identifier).
The syntax is:
We can also use multiple location directives in a given context:
Nginx also provides a few modifiers which can be used in conjunction with the location directive.
Modifier has assigned precedence:
First of all, nginx will check for any exact matches. If it does not exist, it will look for preferential ones. If this match also fails, regex matches will be tested in the order of their appearance. If everything else fails, the last prefix match will be used.
try_files directive
This directive tries different paths and will return whichever is found.
- $uri (/foo.html);
- index.html
- If none is found:404
If we define try_files in a server context, and then define a location that finds all requests, our try_files will not be executed. This happens because try_files in the server context defines its pseudo-location, which is the least specific location possible. Hence, defining location / will be more specific than our pseudo-location.
Thus, we should avoid try_files in a server context:
Other Contexts
split_clients: This context is configured to split the clients that the server receives into categories by labeling them with variables based on a percentage. These can then be used to do A/B testing by providing different content to different hosts.perl / perl_set: These contexts configure Perl handlers for the location they appear in. This will only be used for processing with Perl.map: This context is used to set the value of a variable depending on the value of another variable. It provides a mapping of one variable’s values to determine what the second variable should be set to.geo: Like the above context, this context is used to specify a mapping. However, this mapping is specifically used to categorize client IP addresses. It sets the value of a variable depending on the connecting IP address.types: This context is again used for mapping. This context is used to map MIME types to the file extensions that should be associated with them. This is usually provided with Nginx through a file that is sourced into the mainnginx.confconfig file.charset_map: This is another example of a mapping context. This context is used to map a conversion table from one character set to another. In the context header, both sets are listed and in the body, the mapping takes place.
The Upstream Context
The upstream context is used to define and configure “upstream” servers. This context defines a named pool of servers that Nginx can then proxy requests to. This context will likely be used when you are configuring proxies of various types.
The upstream context should be placed within the http context, outside of any specific server contexts. The form looks like this:
# main context
http { # http context upstream upstream_name { # upstream context server proxy_server1; server proxy_server2; . . . } server { # server context }
}The If Context
The “if” context can be established to provide conditional processing of directives. Like an if statement in conventional programming, the if directive in Nginx will execute the instructions contained if a given test returns “true”.
The if context in Nginx is provided by the rewrite module and this is the primary intended use of this context. Since Nginx will test conditions of a request with many other purpose-made directives, if should not be used for most forms of conditional execution. This is such an important note that the Nginx community has created a page called if is evil.
The problem is that the Nginx processing order can very often lead to unexpected results. The only directives that are considered reliably safe to use inside of these contexts are the return and rewrite directives (the ones this context was created for). Another thing to keep in mind when using an if context is that it renders a try_files directive in the same context useless.
# main context
http { # http context server { # server context location location_match { # location context if (test_condition) { # if context } } }
}The Limit_except Context
The above example would look something like this:
. . .
# server or location context
location /restricted-write { # location context limit_except GET HEAD { # limit_except context allow 192.168.1.1/24; deny all; }
}This will apply the directives inside the context (meant to restrict access) when encountering any HTTP methods except those listed in the context header. The result of the above example is that any client can use the GET and HEAD verbs, but only clients coming from the 192.168.1.1/24 subnet are allowed to use other methods.
The Core Contexts
The Main Context
# The main context is here, outside any other contexts
. . .context { . . .
}The main context represents the broadest environment for Nginx configuration. It is used to configure details that affect the entire application. While the directives in this section affect the lower contexts, many of these cannot be overridden in lower levels.
The Events Context
The “events” context is contained within the “main” context. It is used to set global options that affect how Nginx handles connections at a general level. There can only be a single events context defined within the Nginx configuration.
This context will look like this in the configuration file, outside of any other bracketed contexts:
# main context
events { # events context . . .
}Nginx uses an event-based connection processing model, so the directives defined within this context determine how worker processes should handle connections. Mainly, directives found here are used to either select the connection processing technique to use, or to modify the way these methods are implemented.
Usually, the connection processing method is automatically selected based on the most efficient choice that the platform has available. For Linux systems, the epoll method is usually the best choice.
Other items that can be configured are the number of connections each worker can handle, whether a worker will only take a single connection at a time or take all pending connections after being notified about a pending connection, and whether workers will take turns responding to events.
The HTTP Context
Defining an HTTP context is probably the most common use of Nginx. When configuring Nginx as a web server or reverse proxy, the “http” context will hold the majority of the configuration. This context will contain all of the directives and other contexts necessary to define how the program will handle HTTP or HTTPS connections.
The http context is a sibling of the events context, so they should be listed side-by-side, rather than nested. They both are children of the main context:
# main context
events { # events context . . .
}
http { # http context . . .
}While lower contexts get more specific about how to handle requests, directives at this level control the defaults for every virtual server defined within. A large number of directives are configurable at this context and below, depending on how you would like the inheritance to function.
The Server Context
The “server” context is declared within the “http” context. This is our first example of nested, bracketed contexts. It is also the first context that allows for multiple declarations.
The general format for server context may look something like this. Remember that these reside within the http context:
# main context
http { # http context server { # first server context } server { # second server context }
}This context type is also the first that Nginx must use to select an algorithm. Each client request will be handled according to the configuration defined in a single server context, so Nginx must decide which server context is most appropriate based on details of the request. There are two common options, which differ in their use of domain names:
- listen: The IP address / port combination that this server block is designed to respond to. If a request is made by a client that matches these values, this block will potentially be selected to handle the connection.
- server_name: This directive is the other component used to select a server block for processing. If there are multiple server blocks with listen directives of the same specificity that can handle the request, Nginx will parse the “Host” header of the request and match it against this directive.
The directives in this context can override many of the directives that may be defined in the http context, including logging, the document root, compression, etc. In addition to the directives that are taken from the http context, we also can configure files to try to respond to requests (try_files), issue redirects and rewrites (return and rewrite), and set arbitrary variables (set).
The Location Context
The general syntax looks like this:
location match_modifier location_match { . . .
}# main context
server { # server context location /match/criteria { # first location context } location /other/criteria { # second location context location nested_match { # first nested location } location other_nested { # second nested location } }
}Many of the directives you are likely to see in a location context are also available at the parent levels. New directives at this level allow you to reach locations outside of the document root (alias), mark the location as only internally accessible (internal), and proxy to other servers or locations (using http, fastcgi, scgi, and uwsgi proxying).
How NGINX choose a location block
- NGINX starts with looking for an exact match specified with
location = /some/path/and if a match is found then this block is served right away. - If there are no such exact location blocks then NGINX proceed with matching longest non-exact prefixes and if a match is found where ^~ modifier have been used then NGINX will stop searching further and this location block is selected to serve the request.
- If the matched longest prefix location does not contain ^~ modifier then the match is stored temporarily and proceed with following steps.
- NGINX now shifts the search to the location block containing ~ and ~* modifier and selects the first location block that matches the request URI and is immediately selected to serve the request.
- If no locations are found in the above step that can be matched against the requested URI then the previously stored prefix location is used to serve the request.
NGINX location directive syntax
location [modifier] [URI] { ... ...
}- none: If no modifiers are present in a location block then the requested URI will be matched against the beginning of the requested URI.
- =: The equal sign is used to match a location block exactly against a requested URI.
- ~: The tilde sign is used for case-sensitive regular expression match against a requested URI.
- ~*: The tilde followed by asterisk sign is used for case insensitive regular expression match against a requested URI.
- ^~: The carat followed by tilde sign is used to perform longest nonregular expression match against the requested URI. If the requested URI hits such a location block, no further matching will takes place.
Практический пример поясняющие использование Nginx location
Типовая конфигурация для сайта на PHP при которой применяется Nginx с FPM, статика обрабатывается самим веб-сервером, для изображений дополнительно задается кэширование.
server { listen 80; server_name example.com; root /data/www; location / { index index.html index.php; } location ~\* \.(gif|jpg|png)$ { expires 30d; } location ~ \.php$ { fastcgi_pass localhost:9000; … }
}При обращении к /data/www/script.html за отсутствием других совпадений будет выбран location /data/www, если в URL php скрипт он обработается другим блоком и запрос передастся на обработку на порт 9000, на котором работает PHP-FPM.
Для изображений будет выбран блок в котором устанавливается заголовок expires, затем запрос обрабатывается тем выражением, которое задано для /, т.е. картинки будут запрашиваться в /data/www, если их там нет возникнет ошибка 404.
Matching Location Blocks
Location Block Syntax
location optional_modifier location_match { . . .
}- (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 an equal sign is used, this block will be considered a match if the request URI exactly matches the location given.~: If a tilde modifier is present, this location will be interpreted as a case-sensitive regular expression match.~*: If a tilde and asterisk modifier is used, the location block will be interpreted as a case-insensitive regular expression match.^~: If a carat and tilde modifier is present, and if this block is selected as the best non-regular expression match, regular expression matching will not take place.
Examples Demonstrating Location Block Syntax
location /site { . . .
}location = /page1 { . . .
}location ~ \.(jpe?g|png|gif|ico)$ { . . .
}location ~* \.(jpe?g|png|gif|ico)$ { . . .
}location ^~ /costumes { . . .
}How Nginx Chooses Which Location to Use to Handle Requests
- 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.
- First, Nginx looks for an exact match. If a location block using the
=modifier is found to match the request URI exactly, this location block is immediately selected to serve the request. - If no exact (with the
=modifier) location block matches are found, Nginx then moves on to evaluating non-exact prefixes. It discovers the longest matching prefix location for the given request URI, which it then evaluates as follows:- 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.
- If the longest matching prefix location has the
- 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:
- index
- try_files
- rewrite
- error_page
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.
index index.html;
location = /exact { . . .
}
location / { . . .
}location = /exact { index nothing_will_match; autoindex on;
}
location / { . . .
}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.
root /var/www/main;
location / { try_files $uri $uri.html $uri/ /fallback/index.html;
}
location /fallback { root /var/www/another;
}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:
root /var/www/main;
location / { rewrite ^/rewriteme/(.*)$ /$1 last; try_files $uri $uri.html $uri/ /fallback/index.html;
}
location /fallback { root /var/www/another;
}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:
root /var/www/main;
location / { error_page 404 /another/whoops.html;
}
location /another { root /var/www;
}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.
Optimizing Performance for Serving Content
Speed of the loading is a crucial factor for serving any content. Making minor optimizations to our NGINX configuration may increase the productivity and helps to reach optimal performance.
By default, NGINX controls file transmission itself and copies the file into the buffer before sending it. When we enable the sendfile directive, then it will eliminate the step of copying the data into the buffer and enables direct copying data from one file descriptor to another. Alternatively, to stop a fast connection from entirely occupying the worker process, we can use the sendfile_max_chunk directive to limit the amount of data transferred in a single sendfile() call (in this example, to 1 MB):
Add the tcp_nopush directive together with the sendfile in the directive. This enables NGINX to send HTTP response headers in one packet right after the chunk of data has been obtained from the sendfile().
Принципы обработки location и директивы listen
Nginx считывает конфигурацию блоками, они заключены в location, которые находятся в блоке server. Расположение location относительно друг друга не имеет значения, вперед обрабатывается всегда тот, что имеет высший приоритет согласно логике работы Nginx.
server {
location {
… }
}server характеризуется адресом, портом и запрашиваемым доменным именем.
Они определяются директивой listen. Если один или несколько параметров не указаны используются значения по умолчанию.
Так при отсутствующем адресе будет использован 0.0.0.0, при отсутствующем порте 80 для пользователя root, 8080 для любого другого пользователя.
Более точное явное совпадение IP адреса и порта обслуживается в первую очередь.
Если и порт и адрес заданы для двух location — идет сравнение server_name.
При отсутствии server_name, но присутствии IP адреса и порта блок всегда будет выполняться первым даже если в другом location есть server_name, совпадающий с запрашиваемым, но не указан порт или адрес.
Если сравнение происходит на уровне server_name работает следующая логика:
- при полном совпадении значений выбирается первое найденное совпадение (example.com)
- если полного совпадения нет — происходит поиск с учетом * (*xample.com) в начале по маске, выбирается самый длинный server_name
- если таких нет — происходит поиск с учетом * в конце по маске, выбирается самый длинный server_name (example.*)
- при отсутствии совпадений начинают рассматриваться регулярные выражения (начинающиеся с ~), первое совпадение запоминается
- когда ничего из перечисленного не подходит используется default блок
Understanding Nginx Configuration Contexts
This guide will cover the structure of the main Nginx configuration file. The location of this file will depend on how Nginx was installed. On many Linux distributions, the file will be located at /etc/nginx/nginx.conf. If it does not exist there, it may also be at /usr/local/nginx/conf/nginx.conf or /usr/local/etc/nginx/nginx.conf.
Because contexts can be layered within one another, Nginx allows configurations to be inherited. As a general rule, if a directive is valid in multiple nested scopes, a declaration in a broader context will be passed on to any child contexts as default values. The child contexts can override these values. It is important to note that an override to any array-type directives will replace the previous value, not add to it.
Directives can only be used in the contexts that they were designed for. Nginx will throw an error when reading a configuration file with directives that are declared in the wrong context. The Nginx documentation contains information about which contexts each directive is valid in, making it a useful reference.
Below, we’ll discuss the most common contexts that you’re likely to come across when working with Nginx.
How Nginx Decides Which Server Block Will Handle a Request
Parsing the listen Directive to Find Possible Matches
The listen directive can be set to:
- An IP address/port combo.
- A lone IP address which will then listen on the default port 80.
- 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.
- Nginx translates all “incomplete”
listendirectives by substituting missing values with their default values so that each block can be evaluated by its IP address and port. Some examples of these translations are:- A block with no
listendirective uses the value0.0.0.0:80. - A block set to an IP address
111.111.111.111with no port becomes111.111.111.111:80 - A block set to port
8888with no IP address becomes0.0.0.0:8888
- A block with no
- Nginx then attempts to collect a list of the server blocks that match the request most specifically based on the IP address and port. This means that any block that is functionally using
0.0.0.0as its IP address (to match any interface), will not be selected if there are matching blocks that list a specific IP address. In any case, the port must be matched exactly. - If there is only one most specific match, that server block will be used to serve the request. If there are multiple server blocks with the same level of specificity matching, Nginx then begins to evaluate the
server_namedirective of each server block.
server { listen 192.168.1.10; . . .
}
server { listen 80; server_name example.com; . . .
}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.
- Nginx will first try to find a server block with a
server_namethat matches the value in theHostheader of the request exactly. If this is found, the associated block will be used to serve the request. If multiple exact matches are found, the first one is used. - If no exact match is found, Nginx will then try to find a server block with a
server_namethat matches using a leading wildcard (indicated by a*at the beginning of the name in the config). If one is found, that block will be used to serve the request. If multiple matches are found, the longest match will be used to serve the request. - If no match is found using a leading wildcard, Nginx then looks for a server block with a
server_namethat matches using a trailing wildcard (indicated by a server name ending with a*in the config). If one is found, that block is used to serve the request. If multiple matches are found, the longest match will be used to serve the request. - If no match is found using a trailing wildcard, Nginx then evaluates server blocks that define the
server_nameusing regular expressions (indicated by a~before the name). The firstserver_namewith a regular expression that matches the “Host” header will be used to serve the request. - If no regular expression match is found, Nginx then selects the default server block for that IP address and port.
Examples
In this example, if the Host header of the request was set to host1.example.com, the second server would be selected:
server { listen 80; server_name *.example.com; . . .
}
server { listen 80; server_name host1.example.com; . . .
}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.
server { listen 80; server_name www.example.*; . . .
}
server { listen 80; server_name *.example.org; . . .
}
server { listen 80; server_name *.org; . . .
}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.
server { listen 80; server_name host1.example.com; . . .
}
server { listen 80; server_name example.com; . . .
}
server { listen 80; server_name www.example.*; . . .
}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.
server { listen 80; server_name example.com; . . .
}
server { listen 80; server_name ~^(www|host1).*\.example\.com$; . . .
}
server { listen 80; server_name ~^(subdomain|set|www|host1).*\.example\.com$; . . .
}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.
NGINX location block examples
1. NGINX location matching all requests
location / { ...
}2. NGINX location matching exact URL
location = /images { ...
}3. NGINX location block for a directory
location /images/ { ... ...
}4. NGINX location RegEx Example
location ^~ /images { ... ...
}5. NGINX location block for image/css/js file types
location ~* .(png|ico|gif|jpg|jpeg|css|js)$ { ... ...
}6. NGINX location RegEx Case Sensitive Match
location ~ /images { ... ...
}7. NGINX location RegEx Case Insensitive Match Example
location ~* /images { ... ...
}Conclusion
Always check Nginx’s documentation for information about which contexts a directive can be placed in and to evaluate the most effective location. Taking care when creating your configurations will improve maintainability and also often increase performance.
Next, you can learn how to configure password authentication with Nginx.






