A useful tool for controlling the handling of several kinds of requests is the Nginx location
directive. Specifying rules in the location
directive lets you apply particular setups, divert requests to different areas of your application, or altogether refuse some requests. Using the Nginx location
directive, you can maintain effective request management, which is important for improving web applications efficiency, security, and functionality.
The Nginx location
directive is defined in the configuration file nginx.conf
. Below you can see its basic syntax:
location [modifier] uri { ... }
modifier
: An optional parameter that defines the type of match (e.g., exact
, prefix
, regex
).uri
: The URI to be matched.proxy_pass
, root
, index
).An exact match occurs when the requested URI exactly matches the specified string.
location = /exact-match {
root /var/www/html;
index index.html;
}
In this example, only requests to /exact-match
will be processed by this location block.
You can incorporate a condition using an if
statement as well. Keep in mind that Nginx does not have a direct counterpart to the conventional if-else
statement seen in various programming languages. However, similar functionality can be achieved by combining multiple if
statements with other directives to simulate conditional branching.
location = /exact-match {
root /var/www/html;
index index.html;
if ($http_user_agent ~* "Chrome") {
add_header X-Browser "Chrome";
}
}
In this case, if the user agent is identified as Chrome, the response will include an extra X-Browser header.
A prefix match is the most common type and matches any URI that starts with the specified string.
location /prefix {
root /var/www/html;
index index.html;
if ($request_method = POST) {
return 405; # Method Not Allowed
}
}
This location block will handle any request beginning with /prefix
—like /prefix/page1
or /prefix/page2
. Should the request method be POST
, Nginx results in a 405 Method Not Allowed
status.
For more difficult matching scenarios, regular expressions are useful. In Nginx, the regular expression match may contain wildcards — characters that fit any character or collection of characters. Common wildcards in Nginx regular expressions are:
.
: Matches any single character..*
: Matches any sequence of characters (including no characters).^
: Matches the beginning of a string.$
: Matches the end of a string.location ~* \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
if ($request_uri ~* "/admin") {
return 403; # Forbidden
}
if ($request_uri !~* "/admin") {
add_header X-Admin "Not Admin";
}
}
In this example:
~*
modifier indicates a case-insensitive regular expression match.\.php$
matches any URI ending with .php
(e.g., index.php
, test.PHP
)./admin
, Nginx returns a 403 Forbidden
status./admin
, an X-Admin
header is added indicating "Not Admin".You can use regular expression with the ~*
modifier for case-insensitive matching.
location ~* \.jpg$ {
root /var/www/images;
if ($http_referer !~* "^https?://(www\.)?example\.com") {
return 403; # Forbidden
}
}
This matches any URI ending with .jpg
, .JPG
, .Jpg
, etc., and only serves the image files if the referer is from example.com. Otherwise, it returns a 403 Forbidden
status.
Managed solution for Backend development
The priority and order of location blocks are critical for correctly processing requests. Nginx follows these rules:
(=)
: These have the highest priority.(~ or ~*)
: Evaluated in the order they are defined in the configuration file.location = /exact {
# highest priority
}
location ~* \.jpg$ {
# lower priority than exact match
}
location / {
# lowest priority
}
Nginx allows nesting of location blocks within other location blocks for more granular control.
location /nested {
location /nested/subnested {
root /var/www/html;
}
root /var/www/html;
}
In this example, requests to /nested/subnested
will be processed by the inner location block, while /nested
(but not /nested/subnested
) will be processed by the outer location block.
Let's consider a practical example of configuring a local web server with multiple location blocks.
server {
listen 80;
server_name localhost;
# Root location block
location / {
root /var/www/html;
index index.html;
}
# Exact match for a specific page
location = /about {
root /var/www/html;
index about.html;
}
# Prefix match for an API endpoint
location /api {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Regular expression match for PHP files
location ~ \.php$ {
root /var/www/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
# Case insensitive match for image files
location ~* \.(jpg|jpeg|png|gif|ico)$ {
root /var/www/images;
}
# Nested location blocks for admin section
location /admin {
root /var/www/admin;
index index.html;
location /admin/stats {
proxy_pass http://localhost:8080/stats;
}
}
}
In this configuration:
/var/www/html
./about
are served by the exact match block pointing to about.html
./api
prefix is proxied to a backend service running on port 3000./var/www/images
./admin
and /admin/stats
with different settings.Nginx main configuration file contains the core configuration directives for the Nginx server. Nginx config file location is usually /etc/nginx/nginx.conf
.
After changing the Nginx configuration, you must reload the service to apply the modification. This can be done without dropping active connections by running:
sudo systemctl reload nginx
It's important to verify that each location block works as intended before deploying or relying on a NGINX configuration. We will provide simple ways to test your setup, catch misconfigurations early, and troubleshoot common issues using built-in tools like curl and log files.
Check configuration syntax before applying changes this way:
sudo nginx -t
Next, reload NGINX to apply changes without dropping active connections:
sudo systemctl reload nginx
Test location behavior with curl and send requests to check if the correct location block responds:
curl -I http://localhost/about
curl -X POST http://localhost/prefix/form
curl -H "User-Agent: Chrome" http://localhost/exact-match
Check for status codes, headers, and content.
View request handling and errors in real-time:
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
Let's write down a location block troubleshooting checklist.
To keep things safe, limiting who can access private routes like /admin
, /config
, or internal tools is smart. The allow and deny directives in NGINX let you control entry based on an IP address.
location /admin {
allow 192.168.1.100;
deny all;
root /var/www/admin;
index index.html;
}
The /admin
path can only be reached by the client at 192.168.1.100 in this case. A 403 Forbidden
answer will be sent to any other IP that tries to reach it. You can also allow multiple addresses or ranges and deny the rest. This method is simple and effective for securing access without relying on authentication or external tools.
Depending on how your location block is set up, you need to use the right directive when sending static files. This could be root or alias. Misusing these can cause NGINX to fail to locate files correctly.
Here’s a quick comparison:
Directive |
Behavior |
Example URI |
Config Path |
Resulting File Path |
root |
Appends URI after match |
|
|
|
alias |
Replaces matched URI prefix |
|
|
|
Example using alias, where the request to /files/manual.pdf
will serve the file at /data/downloads/manual.pdf
:
location /files/ {
alias /data/downloads/;
}
Note: When you use alias, always add a backslash (/
) to the end of the path if your address ends in /
. This will keep the paths from not matching.
A solid understanding of the location directive is essential to refine the management of the request handling. This includes an understanding of different matches — exact (=
), prefix (/
), and regular expression-based (~
, ~*
) — and how Nginx prioritizes them. Using them right can significantly impact performance and behavior of your website.
You can also nest location blocks to apply more targeted rules within broader contexts, giving you tight control over how different URLs are processed. Mastering these patterns helps build a configuration that's both clean and highly efficient.