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 becomes 111.111.111.111:80
    • A block set to port 8888 with no IP address becomes 0.0.0.0:8888
  • 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;
    . . .
}