BLOCK CONFIGURATION WITH NGINX

Nginx separates the configuration into blocks, which work in a hierarchical fashion. Every time a request is made, the web server begins a process to determine which configuration block should be used to serve that request. The two main blocks used in the Nginx configuration file are:

  • server blocks
  • locations blocks

Here we discuss mainly the locations blocks and its location block directives;

Below is the general structure of an Nginx location block. The modifier is optional. The location_match in the example below defines what will be checked against the request URI.(the part of the request that comes after the domain name or IP address/port).

Example for location block form,

location optional_modifier location_match {

    . . .

}

Regular expressions (RE) or literal strings can be used to define the modifier. If a modifier is present in the location block, this will change the way that Nginx matches the location block.

The most important modifiers are:

In the following example the prefix location / will match all requests but will be used as a last resort if no matches are found.

location / {

    …

}

= :The equal sign can be used if the location needs to match the exact request URI. When this modifier is matched, the search stops right here.

location  = / {

    # Only matches the / query.

}

  • Nginx searches for an exact match. If a = modifier exactly matches the requested URI, this specific location block is chosen right away.

~: If a tilde modifier is present, this location will be interpreted as a case-sensitive regular expression match

for Example ,

 location ~ \.(jpe?g|png|gif|ico)$ {

    . . .

}

a location that should be interpreted as a case-sensitive regular expression, this block could be used to handle requests for /images.jpg, but not for /name.png .

~*  :Tilde followed by an asterisk modifier means that the location will be processed as a case-insensitive Regular expressions match.

for Example ,

 location ~* \.(jpe?g|png|gif|ico)$ {

    . . .

A block that would allow for case-insensitive matching similar to the above. Here, both /images.jpg and /name.png could be handled by this block.

^~ :Assuming this block is the best non-RE match, a carat followed by a tilde modifier means that RE matching will not take place.

for Example ,

location ^~ /img/ {

    # Queries beginning with /img/ and then stops searching.

}

Finally, this block would prevent regular expression matching from occurring if it is determined to be the best non-regular expression match.

As you see, the modifiers indicate how the location block should be interpreted.

                 BASIC REDIRECT URL ON NGINX 

This is a general directive that permits the predictable design of location blocks; sometimes certain directives within the location can trigger a new search as well. In other words, the ‘just one location block’ rule has a few exceptions. Those exceptions might not align with the expectation of the location blocks. Therefore,  they may not address the request as expected.

These internal redirects can end up manifesting due to some directives including:

  • index
  • rewrite
  • error_page
  • try_file

If you use the index directive it will always result in an internal redirect during request handling. While finding location matches typically end the algorithm execution to speed up the selection process, if the location match found is a directory, the request will likely be redirected to another location to formally be processed.

#index

The following first location matches with a request URI of /exact. However, to process the request, the index directive that the location block inherits redirects the request to a secondary block:

index index.html;

location = /exact {

    . . . 

}

location  / {

    . . .

}

if the execution needs to stay within the primary block, another scheme will need to process the request to the directory. One way is to do this is to set up an invalid index for the block in question, and activate auto index instead:

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).

 #try_files

Usually the Nginx try_files directive to recursively check if files exist in a specific order and serve the file located first.

The try_file directive is in the server and location blocks and specifies the files and directories in which Nginx should check for files if the request to the specified location is received. A typical try_files directive syntax is ;

location / {

    try_files $uri $uri/ /default/index.html;

}

The location/block specifies that this is a match for all locations unless explicitly specified location /<name>

Inside the second block, the try_files means if Nginx receives a request to the URI that matches the block in the location, try the $uri first, and if the file is present, serve the file.

For example, if a request such as https://example.com/blocks/io.sh is received, Nginx will first look for the file inside the /blocks directory and serve the file if available.

The next part (/default/index.html) specifies a fallback option if the file is not in the first param. For example, if the file is not in the /block directory, Nginx will search for the /default directory and serve the file if it exists.

NOTE: Nginx try_files directive recursively searches for files and directories specified from left to right until it finds ones. Specifying this directive in the location / can cause performance issues, especially on sites with massive traffic. Therefore, we should explicitly specify the location block for try_files.

#rewrite

Another directive that results in a redirect to another location block is the rewrite directive. Nginx will search for a new matching location based on the result of the rewrite directive when the last parameter is used. 

Redirecting a single file:

if ($request_filename ~ oldfile.html){

rewrite ^ http://example.com/newfile.html? permanent;

}

This redirects requests from example.com/oldfile.html to example.com/newfile.html.

Redirecting an entire site:

if ($request_filename ~ /*){

        rewrite ^ http://example.com? permanent;

}

This redirects requests to your site to example.com. Change example.com to any site you’d like to redirect to.

#return

In some situations, you may want to redirect pages instead of redirecting domains. The return directive inside the location block enables you to redirect specific pages to a new location.

location = /tutorial/learning-nginx {

     return 301 $scheme://example.com/nginx/understanding-nginx

}

#error_page

Another directive that can lead to similar internal redirects to that of try_again is the error_page directive. You can use that when you encounter particular error codes in processing. When a try_files directive is set, the error_page directive will likely never be executed. That’s because that directive will handle the full life cycle of the request.

For example,

root /var/www/main;

location / {

    error_page 404 /another/whoops.html;

}

location /another {

    root /var/www;

}

In this case, every request will be processed by the first block serving files from /var/www/main. This does not apply to those requests that start with /another. But if a file were to not be found, there will be an internal redirect initiated to /another/whoops/html. This will lead to another location search. In turn, it will direct the request to a secondary block, with that file being addressed out of /var/www/another/whoops.html.

SUMMERY

Understanding the ways that Nginx processes client requests can make our job as an administrator much easier. we will be able to know which server block Nginx will select based on each client request. we will also be able to tell how the location block will be selected based on the request URI. Overall, knowing the way that Nginx selects different blocks will give you the ability to trace the contexts that Nginx will apply in order to serve each request.

Leave a Reply

Your email address will not be published. Required fields are marked *