Deep understanding of Nginx's server block selection algorithm
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 be used as a web server, mail server, or reverse proxy server.
In this article, we will discuss some details that determine how Nginx handles client requests. Understanding these can help us be more comfortable when designing Server and Location, and not be confused by some request phenomena.
Nginx block configuration
Nginx logically divides the configuration used to serve different content into blocks, which exist in a hierarchy. Every time a client request is made, Nginx starts to determine which configuration blocks should be used to handle the request. This decision-making process is what we will discuss next.
The main blocks we will discuss are Server
the block and Location
the block.
A server block is a subset of the Nginx configuration that defines a virtual server that handles requests of a defined type. Administrators often configure multiple server blocks and decide which block should handle which connection based on the requested domain name, port, and IP address.
Location blocks are located within the Server block and are used to define how Nginx should handle requests for different resources and URIs. These blocks can be used to subdivide the URI space in any way the administrator likes. This is a very flexible model.
How Nginx decides which server block to use to handle a request
Since Nginx allows administrators to define multiple Server blocks that act as separate virtual web server instances, it requires a process to determine which of these blocks will be used to handle a request.
It does this through a defined system of checks that are used to find a best match. The main Server block directives that Nginx looks at during this process are listen
the and server_name
directives.
Parse the listen directive to find possible matches
First, Nginx looks at the IP address and port of the request. It then matches it with the listening directives of each server to build a list of server blocks that can potentially resolve the request.
The listen directive usually defines the IP address and port that the Server block will respond to. If no listen directive is defined, the default value of 0.0.0.0:80 is used (or 0.0.0.0:8080 if Nginx is run by a normal non-root user). This allows these blocks to respond to any request to port 80, but this default value does not have much weight in the selection process of the Server block.
The listen directive can be set to:
- IP address/port combination.
- A separate IP address will then listen on the default port 80.
- A separate port and it will listen on each interface on that port.
- The path to the Unix socket.
The last option will usually only have an impact when passing requests between different servers.
When trying to determine which server block to send a request to, Nginx will first try to decide using the following rules based on the specificity of the listen directive:
- Nginx completes all "incomplete" listen directives by replacing missing values with default values, so that each block can be detected by its IP address and port. Here are some examples of completion:
- Blocks without a listen directive use the value 0.0.0.0:80.
- The block set to IP address 111.111.111.111 without a port becomes 111.111.111.111:80
- A block set to port 8888 with no IP address becomes 0.0.0.0:8888
- Nginx then tries to gather a list of server blocks that best matches the request based on IP address and port. This means that any block that functionally uses 0.0.0.0 as its IP address (to match any interface) will not be selected if there is a matching block that lists a specific IP address. The port must match exactly regardless.
- 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 match, Nginx then starts examining the server_name directives of each Server block.
It is important to understand that Nginx will only detect the server_name directive if it cannot distinguish between Server blocks using the listen directive. For example, if example.com is hosted on port 80 on 192.168.1.10, then in this example, requests for example.com will always be served by the first block, despite the server_name directive in the second block.
server {
listen 192.168.1.10;
. . .
}
server {
listen 80;
server_name example.com;
. . .
}
Parse the server_name directive and select the matching item
Next, to further detect requests with the same specific listen directive, Nginx checks the request's Host header. This value contains the domain or IP address that the client was actually trying to access.
Nginx then matches the server_name directive in the Server block selected by the listen directive to match the final block. Nginx uses the following formula to match:
- Nginx will first try to find a server block whose server_name exactly matches the value in the request's Host header. If found, the associated block will be used to serve the request. If multiple exact matches are found, the first one is used.
-
If there is no exact match, Nginx will try to match a Server block for server_name using a leading wildcard (indicated by a at the beginning of the name in the configuration
*
). If found, that block will be used to serve the request. If multiple matches are found, the longest match will be used to handle the request. -
If no match is found using the leading wildcard, Nginx then looks for a server block with a server_name that matches using the trailing wildcard (
*
indicated by a server name ending with in the configuration). If found, that block is used to serve the request. If multiple matches are found, the longest match is used to serve the request. - If no match is found using the trailing wildcard, Nginx then matches server blocks that define a server_name using a regular expression (indicated by a ~ before the name). The first server_name with a regular expression that matches the "Host" header will be used to serve the request.
- If no regular expression match is found, Nginx then chooses the default Server block for that IP address and port.
Each IP address/port combination has a default Server block, which is used when a definitive match cannot be determined using the above method. This will be the first block in the configuration for the IP address/port combination, or a block that contains a default_server option as part of the listen directive (which overrides the first-found algorithm). There can only be one default_server declaration per IP address/port combination.
If a server_name is defined that exactly matches the Host header value, that Server block is selected to handle the request.
In the following example, if the request's Host header is set to host1.example.com, the second Server block will 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 suitable starting wildcard. The longest match starting with the wildcard will be chosen to satisfy the request.
In this example, if the request's Host header is www.example.org, the second Server block will be selected:
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 using the wildcard, Nginx will use the wildcard at the end of the expression to see if there is a match. At this point, the longest match ending with the wildcard will be selected to handle the request.
For example, if the request's Host header is set to www.example.com, the third Server block will be selected:
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 match is found, Nginx will continue trying to match the server_name directive using a regular expression. The first matching regular expression will be selected to respond to the request.
For example, if the request has a Host header set to www.example.com, the second Server block will be selected to satisfy 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 can satisfy the request, the request will be passed to the default Server matching the IP address and port.
For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.
Related Articles
Nginx load balancing settings
Publish Date:2025/03/18 Views:198 Category:NETWORK
-
At this stage, load balancing is a widely used technology. Nginx, as a load balancing server for http, is being used more and more widely. There are three ways to set up Nginx load balancing: Round-robin - This method distributes access req
Nginx load balancing health_check analysis
Publish Date:2025/03/18 Views:54 Category:NETWORK
-
In Nginx load balancing, it is difficult to guarantee that every application server can run normally all the time. However, we can set Nginx to detect these application servers and detect which of them are inaccessible. There are two ways t
HTTP2 Tutorial - How to Configure HTTP2 with Nginx
Publish Date:2025/03/17 Views:195 Category:NETWORK
-
HTTP2 was officially released in 2015. If your website is still using HTTP/1.1, you may be out of date. Don't worry, here we will see how to use Nginx to upgrade your website to HTTP2. Install Nginx I feel that this column is redundant. Sin
In-depth understanding of Nginx Location block matching algorithm
Publish Date:2025/03/17 Views:61 Category:NETWORK
-
Similar to the process that Nginx uses to select the Server block that will handle a request , Nginx also has an established algorithm to decide which Location block within a Server block to use to handle a request. location block syntax
Nginx - How to fix the "ssl" Directive Is Deprecated, Use "listen ... ssl"
Publish Date:2025/03/17 Views:150 Category:NETWORK
-
When updating nginx to a newer version, we may encounter deprecated configurations. Nginx uses a YAML-like definition format to create configurations. This format has evolved over time by adding, removing, or changing keywords. This article
How to fix the Unknown "connection_upgrade" Variable error in Nginx
Publish Date:2025/03/17 Views:91 Category:NETWORK
-
When using Websockets or configuring a server with nginx, we may encounter the `$connection_upgrade` variable in the nginx configuration. The $connection_upgrade variable is not available by default. However, it is recommended to define and use it in
How to fix Response Status 0 Worker Process Exited on Signal 11 in Nginx
Publish Date:2025/03/17 Views:81 Category:NETWORK
-
Actually, let's clarify first: HTTP does not have status code 0 (zero). The problem is that the nginx worker process died while handling the request, so the connection was broken, resulting in an error without any response data.
Nginx is running but not serving sites
Publish Date:2025/03/17 Views:86 Category:NETWORK
-
We recently installed nginx version 1.17 on a new machine. The configuration created in sites-available` was symlinked to `sites-enabled`, but nginx is not serving any domains.
How Nginx and uWISG servers work together
Publish Date:2025/03/17 Views:70 Category:NETWORK
-
Nginx and uWISG are two commonly used server software that can work together to provide more stable and efficient network services. This article will introduce in detail the working principle of Nginx and uWISG, and how to configure them to achieve op