How Nginx Decides Which Server Block Will Handle a Request ?
Nginx looks at the IP address and the port of the request. It matches this against the listen directive of each server to build a list of the server blocks that can possibly resolve the request.
The listen
directive typically defines which IP address and port that the server block will respond to. By default, any server block that does not include a listen directive is given the listen parameters of 0.0.0.0:80
(or 0.0.0.0:8080
if Nginx is being run by a normal, non-root user). This allows these blocks to respond to requests on any interface on port 80, but this default value does not hold much weight within the server selection process.
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(This option will only have implications when passing requests between different servers).
When trying to determine which server block to send a request to, Nginx will first try to decide based on the specificity of the listen
directive using the following rules:
- Nginx translates all “incomplete” listen directives 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 listen directive uses the value
0.0.0.0:80
. - A block set to an IP address
111.111.111.111
with no port becomes111.111.111.111:80
- A block set to port
8888
with no IP address becomes0.0.0.0:8888
- A block with no listen directive uses the value
- 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.0
as 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_name
directive of each server block.
It is important to understand that Nginx will only evaluate the server_name
directive when it needs to distinguish between server blocks that match to the same level of specificity in the listen
directive.
For instance, if example.com
is hosted on port 80
of 192.168.1.10
, a request for example.com
will always be served by the first block in this example, despite the server_name
directive in the second block.
server {
listen 192.168.1.10;
. . .
}
server {
listen 80;
server_name example.com;
. . .
}