Nginx Location Directive Explained

nginx location

Nginx location directives are essential when working with Nginx. They can be located within server blocks or other location blocks. This article will help explain how location directives are used to process the URIs of client requests.  

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,
  • and locations blocks.

A server block consists of a subset of configurations that define a virtual server. Multiple server blocks are possible to decide which block will handle the request based on domain name, IP address and port. A location block, on the other hand, is located within a server block and defines how requests are processed for different URIs and resources. The URI space can be separated in pretty much any location block.

Nginx Location Directive Syntax Explained

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.

location optional_modifier location_match {
 . . .
}

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

  • (none) No modifier at all means that the location is interpreted as a prefix. To determine a match, the location will now be matched against the beginning of the URI.
  • =: 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.
  • ~: Tilde means that this location will be interpreted as a case-sensitive RE match.
  • ~*: Tilde followed by an asterisk modifier means that the location will be processed as a case-insensitive RE match.
  • ^~: Assuming this block is the best non-RE match,  a carat followed by a tilde modifier means that RE matching will not take place.

The Process of Choosing Nginx Location Blocks

For each request, Nginx goes through a process to choose the best location block that will be used to serve that request. Nginx does this by comparing the request URI against each location block that has be setup in the configuration. To achieve this, the following process is used:

  • Prefix-based Nginx location matches (=no regular expression). Each location will be checked against the request URI.
  • Nginx searches for an exact match. If a “=” modifier exactly matches the request URI, this specific location block is chosen right away.
  • If no exact (meaning no “=” modifier) location block is found, Nginx will continue with non-exact prefixes. It starts with the longest matching prefix location for this URI, with the following approach:
    • In case the longest matching prefix location has the “^~” modifier, Nginx will stop its search right away and choose this location.
    • Assuming the longest matching prefix location doesn’t use the “^~”modifier, the match is temporarily stored and the process continues.
  • As soon as the longest matching prefix location is chosen and stored, Nginx continues to evaluate the case-sensitive and insensitive regular expression locations. The first regular expression location that fits the URI is selected right away to process the request.
  • If no regular expression locations are found that match the request URI, the previously stored prefix location is selected to serve the request.

Examples of Nginx Location Directives

The following section provides a few examples of Nginx location blocks using a combination of modifiers and location match directives. These examples can be used in your own Nginx configuration and can be modified to suit your needs.

location  = / {
  # Only matches the / query.
}
location /data/ {
  # Any query beginning with /data/ but the process continues searching.
  # Will only be matched if regular expressions don't find a match.
}
location ^~ /img/ {
  # Queries beginning with /img/ and then stops searching.
}
location ~* .(png|gif|ico|jpg|jpeg)$ {
  # Matches requests ending in png, gif, ico, jpg or jpeg. 
  # Any request to the /img/ directory are handled by the location block above.
}

Example how to prevent hotlinking of images:

location ~ .(png|gif|jpe?g)$ {
  valid_referers none blocked yourwebsite.io *.yourwebsite.io;
  if ($invalid_referer) {
  return   403;
  }
}

Reject scripts inside writable directories:

location ~* /(media|images|cache|tmp|logs)/.*.(php|jsp|pl|py|asp|cgi|sh)$ {
  return 403;
}

For more details and examples pertaining to the Nginx location directive, visit the official Nginx website.