The location
directive in Nginx configuration is a powerful tool for defining how different types of requests are processed. By specifying rules in the location
directive, you can direct requests to various parts of your application, apply specific configurations, or block certain requests altogether. This directive enables fine-grained control over request handling, making it essential for optimizing performance, security, and functionality of web applications.
The location
directive is defined in the nginx.conf
configuration file. Its basic syntax is as follows:
location [modifier] uri { ... }
modifier
: An optional parameter that defines the type of match (e.g., exact
, prefix
, regex
).
uri
: The URI to be matched.
Inside the curly braces, you can define various settings and instructions (e.g., 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 also add a condition with if
statement. Please note that in Nginx, there isn't a direct equivalent to the traditional if-else
statement found in many programming languages. However, you can achieve similar functionality by using multiple if
statements and combining them 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";
}
}
Here, if the user agent is Chrome, an additional header X-Browser
is added to the response.
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
}
}
Here, any request starting with /prefix
(like /prefix/page1
or /prefix/page2
) will be handled by this location block. If the request method is POST
, Nginx returns a 405 Method Not Allowed
status.
You can use regular expressions for more complex matching scenarios. In Nginx, the regular expression match can include wildcards, which are characters that match any character or set of characters. Here are some common wildcards used in regular expressions:
.
: 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:
The ~*
modifier indicates a case-insensitive regular expression match.
The pattern \.php$
matches any URI ending with .php
(e.g., index.php
, test.PHP
).
If the requested URI contains /admin
, Nginx returns a 403 Forbidden
status.
If the requested URI does not contain /admin
, an X-Admin
header is added indicating "Not Admin".
To perform case-insensitive matching, you can use the ~*
modifier in a regular expression.
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.
The priority and order of location blocks are critical for correctly processing requests. Nginx follows these rules:
Exact match (=)
: These have the highest priority.
Regular expressions (~ or ~*)
: Evaluated in the order they are defined in the configuration file.
Prefix matches without modifier: These have the lowest priority, but among them, the longest prefix has the highest priority.
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:
The root location serves static files from /var/www/html
.
Requests to /about
are served by the exact match block pointing to about.html
.
The /api
prefix is proxied to a backend service running on port 3000.
PHP files are processed by a FastCGI server.
Image files are served from /var/www/images
.
Nested location blocks are used to handle /admin
and /admin/stats
with different settings.
The main configuration file for Nginx is usually located at /etc/nginx/nginx.conf
. This file contains the core configuration directives for the Nginx server.
After making changes to the Nginx configuration, you need to reload the Nginx service to apply the changes. This can be done without interrupting the current connections by using the following command:
sudo systemctl reload nginx
Understanding and effectively using the location
directive in Nginx is key to fine-tuning request handling for your web server. By mastering exact
, prefix
, regex
, and case-insensitive matches, as well as the priority and order of these directives, you can ensure your Nginx configuration is robust and efficient. Moreover, leveraging nested location blocks allows for precise and granular control over request processing, further enhancing your server’s capabilities.