NGINX Config Decoded

Tags: NGINX, devops



NGINX is a popular webserver in the *nix world. NGINX was created by Igor Sysoev for purpose of improving the performance of a large-scale Apache-based installation. NGINX became a popular alternative to Apache’s httpd due to the initial design considerations which were kept in mind when designing the software. Some interesting insights from a comparison of Apache httpd and NGINX can be found here.

Building a website behind NGINX is a pretty simple affair. Install NGINX and modify the config—mostly one just needs to modify the site-specific configuration and a few configuration parameters in the default NGINX config. However, as the site grows and one needs to define specific routes, do a proxy pass to some other remote site, the complexity of NGINX configuration grows, and this is where most people have a hard time determining how NGINX is actually serving the requests. To be able to understand it, one needs to know some basic things about how NGINX processes the requests sent to it.

NGINX configuration is divided into different blocks and each request is handled by an appropriate configuration block.

There are two main blocks in an NGINX config:

  • Server block
  • Location block


Server blocks 

NGINX allows us to host multiple sites on the same machine with a single instance of NGINX. Server blocks are meant to separate multiple virtualhosts. 

NGINX decides on which server block the request needs to go through two main directives: 

listen 

Upon receiving the request, NGINX first identifies the IP address and port. The listen directive determines which IP and port a particular server block responds to. By default, a server block is given listen parameters of 0.0.0.0:80. The listen directive can be set to a combination of IP address and port, or just an IP address, or just a port or a Unix socket.

server_name

If there are two or more server blocks with the same listen directives, NGINX looks at the server_name directive to find the nearest match. To match the server_name, NGINX looks at the Host header of the request. The Host header contains the IP address or domain name that was used by the client to make the request. 

NGINX will first try to find the server block with server_name that matches the the value in the Host header of the request exactly.

If no exact match is found, NGINX tries to find a server block with a server_name that matches using a leading wildcard. If multiple matches are found, then the longest match is used to determine the server block.

If no match can be found using a leading wildcard, NGINX will try to find a server block with server_name that matches using a trailing wildcard. If multiple matches are found, then the longest match is used to determine the server block.

If no match is found using a trailing wildcard, NGINX will evaluate the server block using regular expressions. The first server block with server_name that matches the regular expression will be used to serve the requests.

If still no match is found, the default server block is used.

For each IP address/port combination, there is a default server block that will be used if no match is found. For an IP address/port combination, a default server block is identified by either using the first block in the configuration or the block that contains the default_server option.

Location blocks 

A location block is a configuration section inside the server block, which is used for the purpose of defining routing. A location block has the following syntax:

location [modifier] match {

}

A match in the above syntax is what NGINX uses to check the request URI. The modifiers are used to determine how NGINX makes the match. The following are modifiers that are allowed in an NGINX configuration:

none   Location is matched against the beginning of the request URI.
= Location is matched if request URI exactly matches the location.
~ A case-sensitive regular expression match is done to find the the location block.
~* A case-insensitive regular expression match is done to find the appropriate location block.
^~ Block is selected as best non-regular expression match.


If you would like to find how your NGINX configuration is behaving against different requests, you might want to try out an online tool available at http://nginx.viraptor.info.

Mayank Joshi
Posted by

Mayank Joshi

Guest Blogger