If you are running Nginx webserver, it is important for you to understand how the location directive works.
Nginx uses location directive to decide what configuration it should apply based on prefix or the pattern in the incoming URL.
For example, from what directory it should serve the image files when an URL ends with *.gif or *.png or any other image filename extension.
In this tutorial, we’ll explain the following with proper examples:
- Default Location Directive Setup
- Change the Default Nginx Root Location (i.e DocumentRoot)
- Define Custom 404 Page Not Found Using Location
- Define Multiple Custom 50x Server Errors using Location
- Serve Your Website Images from a Custom Location
- Exact Match Using = (Equalto Sign) Location Modifier
- Case-Sensitive Regular Expression Match Using ~ (Tilde Sign)
- Case-InSensitive Regular Expression Match Using ~* (Tilde-Asterisk Sign)
- ^~ Best Non RegEx Match (Carat-Tilde Sign)
- Nginx Location Related Error Messages
- Summary of Location Modifiers
- Define Custom Named Location Using @ (At Sign)
- Nginx Location Matching Processing Sequence and Logic
The following is the syntax for the location directive in the nginx configuration file.
syntax: location [modifier] match { }
In the above syntax:
- Modifier is optional
- Match defines what in the URL should be matched to execute the configuration mentioned inside this particular location block.
- When there is no modifier, the match acts just as a prefix string for the incoming URL
- If we use ~ or ~* in the modifier, then the match can be a regular expression.
The context for the location block is “server”. So, you’ll see this inside the server block as shown below.
For example:
server { listen 80; server_name thegeekstuff.com location / { root /var/www/html; index index.html index.htm; } .. .. }
You can have as many location directives as you want for your website.
If you are new to Nginx, you can install it as explained in How to Install and Configure Nginx from Source on Linux
1. Default Location Directive Setup
If you’ve installed Nginx with default configuration, you can view your current location directive values in the default.conf file as shown below.
The main configuration file is: /etc/nginx/nginx.conf.
But, the server and location directive will be in the default.conf file that is located under /etc/nginx/conf.d/default.conf file as shown below.
# vi /etc/nginx/conf.d/default.conf location / { root /usr/share/nginx/html; index index.html index.htm; } location = /50x.html { root /usr/share/nginx/html; }
The default.conf file defines the following two location directives
- / for the default location
- /50x.html for all server errors
2. Change the Default Nginx Root Location (i.e DocumentRoot)
The following example shows how you can change the default DocumentRoot for your Nginx webserver.
The following will serve all files for your Nginx server from a directory that you’ll be defining in the root under “location /”.
For example, the following will serve thegeekstuff.com/index.html file from the /var/www/html directory instead of the default nginx root location.
# vi /etc/nginx/conf.d/default.conf location / { root /var/www/html; index index.html index.htm; }
This is the sample file that we created under /var/www/html for this testing.
# cat /var/www/html/index.html <html> <head> <title>Hello World</title> </head> <body> <h1>Hello World! - New Nginx Root Location</h1> </body> </html>
Note: Anytime you modify nginx configuration file, you should restart nginx using systemctl or service command.
But in most cases, instead of restarting it is good enough if you just reload the configuration as shown below.
# service nginx reload Reloading nginx: [ OK ]
3. Define Custom 404 Page Not Found Using Location
Using location directive you can also configure the file that should be served when nginx encounters a HTTP 404 error code. i.e File Not Found.
To do this, add the following lines to your default.conf file.
# vi /etc/nginx/conf.d/default.conf error_page 404 /404.html; location = /404.html { root /var/www/html/errors; }
In the above:
- error_page – Use this directive to define what type of errors you want to capture. Here we are capturing 404 error. The /404.html says that when 404 error is captured, it should display the /404.html page.
- The location directory then says that this /404.html file should be served from the /var/www/html/errors directory.
- The = modifier next the to the location directive says that the URL /404.html has to match exactly for this configuration to be applied. Basically it says that this configuration will be effective only for the 404 error code.
Since we’ve customized this directory location, create the errors directory and the 404.html file as shown below.
# mkdir -p /var/www/html/errors # cat 404.html <html> <head> <title>404 - Where did it go?</title> </head> <body> <h1>File Not Found: Don't worry. We'll find it for you. Please contact us.</h1> </body> </html>
4. Define Multiple Custom 50x Server Errors using Location
By default, you’ll see something like the following already in the default.conf file.
In this example, I’ve modified the location of the 50x.html file and created a custom page.
One important thing to note here is that, you can redirect multiple HTTP error codes to a single file. As shown here, any server side error codes (including 500, 502, 503 or 504) will be redirected to one error file called 50x.html.
In this example, we’ve custom created this 50x.html file and placed it under errors directory.
error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/www/html/errors; }
Next create the 50x.html file in your custom errors directory.
# cd /var/www/html/errors; # vi 50x.html <html> <head> <title>50x - Server Error</title> </head> <body> <h1>Something went wrong on the server side. Please contact our server admin.</h2> </body> </html>
5. Serve Your Website Images from a Custom Location
Another typical use for a location directive is to specify the directory location from where you like to serve all your website’s image files.
In the following example, anytime you call an URL with /img followed by an image file name, it will be look for the image file under /custom/images directory.
location /img/ { root /custom/images; }
For example, we have the following image files in this directory:
# ls -1 /custom/images/img/ dog.gif cat.gif fish.png parrot.jpg ..
So, when you call thegeekstuff.com/img/cat.gif, it will server the cat.gif from the above directory.
If you are interested in setting up a loadbalancer, then inside the location directive you should use proxy_pass as explained in How to Setup Nginx as loadbalancer for Apache or Tomcat for HTTP/HTTPS
6. Exact Match Using = (Equalto Sign) Location Modifier
Use the = (equal-to sign) as a modifier when you want to match the exact request URI.
To understand this, first, let us use the following simple configuration without the equal-to sign.
location /db { root /data; ... }
In the above, it will match the following URL. All of the following will work.
- URL/db – Will look for index.html file under /data/db
- URL/db/index.html – Will look for index.html file under /data/db
- URL/db/connect/index.html – Will look for index.html file under /data/db/connect
But, when we add the = (equalto sign) location modifier as shown below, the above behavior will change.
location = /db { root /data; }
In the above, it will match only the following EXACT URL. Nothing else will work.
- URL/db – Will work.
- URL/db/index.html – Will not work.
- URL/db/connect/index.html – Will not work.
Important: Also, in the above example, the root value will not be honored. This is because the /db will use the root from the “/” location that was defined earlier. So, when you go to the URL/db, it will really serve the index.html file from /var/www/html/db/ and not from /data/db/ as you would expected.
So, the above with the = (equal-to sign) will serve the following file when you call the URL as thegeekstuff.com/db
# ls -l /var/www/html/db/index.html -rw-r--r--. 1 root root 13 May 8 17:28 /var/www/html/db/index.html
Also, please note that when Nginx matches a particular location directive that has the = modifier, then will not look for any further location directives.
One popular configuration is to setup Nginx as a front-end to your existing Apache/PHP website. For this, you should use reverse proxy as per the instructions from here: How to Setup Nginx Reverse Proxy to Apache/PHP on Linux
7. Case-Sensitive Regular Expression Match Using ~ (Tilde Sign)
When you want to use regular expression match (instead of prefix match), then you should use ~ (tilde sign).
Using ~ will perform case-sensitive match.
The following is a practical example of using ~ location modifier for matching image URLs.
location ~ .(png|gif|ico|jpg|jpeg)$ { }
In the above:
- ~ is for case sensitive regular expression match modifier
- ( ) – all the values inside this regular expression will be considered as keywords in the URL
- | This is the OR operator. i.e png, or gif, or ico, or jpg, or jpeg keyword in the URL will be considered.
- $ at the end means that the specified keyword should be at the end of the URL.
- Basically, the whole regular expression is for any image URL. i.e any URL that ends with an image file.
Let us say, we have the following files in the images directory:
dog.gif
cat.gif
fish.png
parrot.jpg
..
In this case:
- URL/img/dog.gif – This will work as we have dog.gif on our server.
- URL/img/CAT.GIF – This will not work, as we don’t have the upper-case CAT.GIF (we only have lower case cat.gif on the server side). Since we are using ~ which will do a case-sensitive match and will not serve this upper-case CAT.GIF file.
Also, instead of specifying two keywords jpg and jpeg, you can also combine them as shown below using “jpe?g”
location ~ .(png|gif|ico|jpe?g)$ { }
If you want to match the php keyword in the URL (for php websites) and do something with it, then refer to some of the Location examples from here: How to Add Custom File Extension for PHP in Apache and Nginx
8. Case-InSensitive Regular Expression Match Using ~* (Tilde-Asterisk Sign)
This is similar to the above example, but this will perform a case-insensitive regular expression matching.
location ~* .(png|gif|ico|jpg|jpe?g)$ { root /custom; }
In this case:
- URL/img/dog.gif – This will work as we have dog.gif on our server.
- URL/img/CAT.GIF – This will also work, as this will be treated as case-insensitive and nginx will serve the cat.git from the server even though the URL has the uppercase CAT.GIF
9. ^~ Best Non RegEx Match (Carat-Tilde Sign)
When this modifier is used, the matching URL will use this configuration. Basically, this configuration will be used as the prefix match, but this will not perform any further regular expression match even if one is available.
location ^~ /img/ { }
10. Nginx Location Related Error Messages
The following are few of the location related error message that you’ll get when you restart Nginx if something is wrong in the location directive.
If you have multiple location directives with the same prefix match, you’ll get the following “duplicate location” error message:
# service nginx start Starting nginx: nginx: [emerg] duplicate location "/" in /etc/nginx/conf.d/default.conf:45 [FAILED]
If you use the “location” in a wrong context. i.e outside the server, then you’ll get the following error message:
# service nginx restart nginx: [emerg] "location" directive is not allowed here in /etc/nginx/nginx.conf:34 nginx: configuration file /etc/nginx/nginx.conf test failed
You can only use the location modifiers that is allowed by nginx (for example: =). In the following snippet, we are using $ as location modifier which is not allowed by Nginx.
location $ /ab { root /var/www/html1; index index.html index.htm; }
In this case, you’ll receive the following invalid location modifier error message as shown below.
# service nginx restart nginx: [emerg] invalid location modifier "$" in /etc/nginx/conf.d/default.conf:17 nginx: configuration file /etc/nginx/nginx.conf test failed
11. Summary of Location Modifiers
To put things in perspective, the following lists most of the above discussed location examples:
The following = is for exact match. For example: thegeekstuff.com/
location = / { }
The following without any modifier is for / followed by anything. For example: thegeekstuff.com/contact.html
location / { }
The following is for /db. For example: thegeekstuff.com/db/index.html
location /db/ { }
The following is for best prefix match without Reg-Ex. For example: thegeekstuff.com/images/logo.gif
location ^~ /images/ { }
The following is for regular expression match. For example: thegeekstuff.com/db/mysql.jpg
location ~* .(png|gif|ico|jpg|jpeg)$ { }
12. Define Custom Named Location Using @ (At Sign)
You can also use @ (at symbol) in the location directive as shown in the example below.
The following are few things to keep in mind regarding this:
- Use @ to define a named location
- This location is configured as request redirection. This is not used for regular request processing.
- You cannot nest the @ location directives
The following is an example:
location / { try_files $uri $uri/ @custom; } location @custom { rewrite ^/(.+)$ /index.php?_route_=$1 last; }
In the above example:
- First, the @custom itself can be defined inside any other location block. As shown in the above example, this is defined in the 1st location block using try_files.
- Next, the “location @custom” refers to the @custom named location that was defined earlier in any other location block. This custom named location is used in the 2nd location block above.
- Please note that instead of @custom, you can call it anything you like. For example: @database, @myapp, @complexredirect, @misc, @thegeekstuff
13. Nginx Location Matching Processing Sequence and Logic
The following are few things to be considered regarding the Location matching sequence and logic:
- First, the incoming URI will be normalized even before any of the location matching takes place. For example, First it will decode the “%XX” values in the URL.
- It will also resolve the appropriate relative path components in the URL, if there are multiple slashes / in the URL, it will compress them into single slash etc. Only after this initial normalization of the URL, the location matching will come into play.
- When there is no location modifier, it will just be treated as a prefix string to be matched in the URL.
- Nginx will first check the matching locations that are defined using the prefix strings.
- If the URL has multiple location prefix string match, then Nginx will use the longest matching prefix location.
- After the prefix match, nginx will then check for the regular expression location match in the order in which they are defined in the nginx configuration file.
- So, the order in which you define the regular expression match in your configuration file is important. The moment nginx matches a regular expression location configuration, it will not look any further. So, use your important critical regular expression location match at the top of your configuration.
- If there is no regular expression matching location is found, then Nginx will use the previously matched prefix location configuration.
Comments on this entry are closed.
helpful explanation, thanks!