Navigating Nginx: Exploring the Structure and Functions of Each Section in Your nginx.conf File

Ritwik MathRitwik Math
18 min read

Configuration Terminology

Nginx operates with two primary configuration elements: directives and contexts. Directives represent specific configuration options, each serving a particular purpose. These directives are organized within contexts, also known as blocks, which are enclosed within braces ({}). A context may consist of other nested contexts and directives, creating a hierarchical structure that helps manage the server's configuration effectively.

Directives

Nginx directives serve as instructions for configuring the web server. Each directive comprises a name and a corresponding value. For instance, the directive 'listen 80;' instructs the server to accept incoming requests solely on port 80. Directives can be used individually or grouped within a particular context, thereby defining the behavior and characteristics of that specific block or context. For example, within a server block, the 'listen' directive specifies a port number, ensuring that the given server responds exclusively to requests on that particular port.

  1. listen 80: This directive specifies that the server should listen for incoming requests on port 80. Port 80 is the default port for HTTP requests, which means this server will handle regular web traffic.

  2. root /var/www/html: This line tells the server where to find the files it should serve to visitors. In this case, it's set to "/var/www/html", which means the server will look for files in the "/var/www/html" directory and send them to the clients.

  3. index index.html index.htm: This directive sets the default filenames to look for when a visitor accesses a directory without specifying a specific file. In this case, the server will first look for "index.html" and if not found, it will look for "index.htm" and display whichever it finds first.

Nginx efficiently handles requests, eliminating the need to explicitly type 'index.html' in the browser to open a file. It achieves this by utilizing a combination of 'listen,' 'root,' and 'index' directives, ensuring the appropriate response is served to the client automatically.

Context

In Nginx, a context refers to a block or section of the configuration file where directives are grouped together to define specific behavior or settings for a particular scope within the server. Contexts help organize and compartmentalize the configuration, making it easier to manage and understand.

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen 80;

        root /var/www/html;

        location / {
            index index.html index.htm; # This can be written outside of location as well
        }
    }
}

There are several types of contexts in Nginx, each serving a different purpose:

  1. Main/Global Context: The main context is the top-level block in the configuration file. Directives placed directly inside the main context apply globally to the entire Nginx server. user, worker_processes, error_log and pid are in main context.

  2. Events Context: This context is used to configure low-level connection handling and other event-related settings for the Nginx server.

  3. HTTP Context: The HTTP context contains directives related to the HTTP protocol, such as server configurations, proxy settings, and URL handling.

  4. Server Context: Within the HTTP context, server blocks define the settings for individual virtual servers or hostnames.

  5. Location Context: Inside the server block, location blocks define configurations for specific URL patterns or paths.

  6. Upstream Context: This context is used to define groups of servers for load balancing or proxy purposes.

Nginx configurations are organized in a hierarchical structure known as contexts, which resembles a tree-like data structure. Each context can contain directives that define various settings for the Nginx server. When configurations are used within child contexts, they can inherit or override configurations from their parent contexts. For instance, within the HTTP context, the access log is configured to be stored in the "access.log" file. However, in a specific server block, this configuration can be overridden to store the access log in a "custom.log" file.

server {
        listen 80;

        root /var/www/html;

        access_log /var/log/nginx/custom.log;

        location / {
                index index.html index.htm;
        }
}

After restarting Nginx, all incoming requests on port 80 will be logged in the "custom.log" file as per the new configuration set in the server block. The server block's configuration takes precedence over the HTTP context's configuration, allowing for more granular control of log file destinations based on specific server settings.

Server Context

In Nginx, the server context refers to a configuration block that defines the settings for a virtual server or hostname. Each server block represents a distinct server configuration within the Nginx server. You can have multiple server blocks, each catering to different domains or subdomains, allowing Nginx to serve multiple websites or applications on the same server.

server {
        listen 80;

        root /var/www/html;

        access_log /var/log/nginx/custom.log;

        location / {
                index index.html index.htm;
        }
}

server {
        listen 81;

        root /var/www/alternate;

        index index.html index.htm;
}

In the given Nginx configuration, there are two separate server contexts, each defining settings for different virtual servers that will listen on different ports. The presence and placement of the index directive in the two server contexts illustrate the tree-like structure of Nginx contexts.

Location Context

In Nginx, the location context is a configuration block that allows you to define how the server should handle requests for specific URL patterns or paths. The location context is a powerful directive that enables you to customize how Nginx responds to different types of requests.

The location context in Nginx is unique compared to other contexts, as it takes a parameter called the Uniform Resource Identifier (URI). This URI parameter allows you to specify different ways of matching requests within the location context.

In the location context, you can define how Nginx should handle incoming requests based on the URI. There are several ways to match URIs in the location context, including:

Exact Match: You can use an exact URI to precisely match requests with a specific path.

location = /greet {
    add_header Content-Type text/plain;
    return 200 "Hello Developers!";
}

Prefix Match: It refers to the matching of requests that start with a specific URI prefix. In this type of matching, Nginx looks for the specified prefix at the beginning of the request's Uniform Resource Identifier (URI) to determine if the location block should be used to handle the request.

location /greet {
    add_header Content-Type text/plain;
    return 200 "Hello Developers!";
}

It will match any request that starts with greet. Even though the request URI has '/' in the request.

Regular Expression Match: Use a regular expression to match more complex URI patterns. It has greater priority than prefix match.

location /greetA {
    add_header Content-Type text/plain;
    return 200 "Prefix match";
}

location ~ /greet[A-Z] {
    add_header Content-Type text/plain;
    return 200 "Hello Developers!";
}

The Regular Expression (regex) location context matches any request that starts with "greet" and is followed by any capital letter (A-Z). As the Regular Expression match takes precedence over other location contexts, requests satisfying this pattern will be handled using this context. The regex location context captures requests like "greetA", "greetB", "greetX", etc., and processes them based on the directives specified within this context. This higher priority allows for specific handling of requests that match the defined Regular Expression pattern, giving you fine-grained control over how Nginx responds to such requests.

Like prefix match anything after this pattern will be handled by this location context.

Preferential Prefix Match: The Preferential Prefix Match location in Nginx works similarly to the prefix match, but it takes higher priority over regular expression matches. If a URL matches both a Preferential Prefix Match location and a regular expression location, Nginx will use the Preferential Prefix Match location to handle the incoming request.

In other words, when there are overlapping location patterns, the Preferential Prefix Match location will be chosen over the regular expression location if the URL matches both. This allows you to prioritize specific handling for certain URL patterns using the Preferential Prefix Match while still using regular expressions for more complex matching if needed.

The Preferential Prefix Match provides a convenient way to ensure that certain URL patterns take precedence, giving you more control over how Nginx processes incoming requests when there are potential conflicts in location matching.

location ^~ /greetA {
    add_header Content-Type text/plain;
    return 200 "Prefix match";
}

Case-Insensitive Regular Expression Match: Perform a case-insensitive match for the URI, unlike a normal Regular Expression match.

location ~* /greet[A-Z] {
    add_header Content-Type text/plain;
    return 200 "Hello Developers!";
}

MatchPriority
Exact Match4
Preferential Prefix Match3
Case-Insensitive Regular Expression Match2
Regular Expression Match2
Prefix Match1

Variables

Nginx provides a variety of important variables that you can use in your configuration to access information about incoming requests, server settings, and other relevant data. Here are some of the commonly used and important Nginx variables:

  1. $uri: The request URI (without the query string).

  2. $args: The query string part of the request URI (everything after the ?).

  3. $arg_: It is a prefix used to access query string parameters (arguments) from the requested URI.

  4. $request_uri: The full original request URI, including the query string.

  5. $request_method: The HTTP request method (e.g., GET, POST, etc.).

  6. $http_user_agent: The User-Agent header from the request, represents the client's browser or user agent.

  7. $http_referer: The Referer header from the request, indicates the URL of the page that referred to the current request.

  8. $host: The hostname from the request, which is useful for virtual hosting scenarios.

  9. $server_name: The server_name value from the server block, is useful in cases of multiple server blocks.

  10. $remote_addr: The IP address of the client making the request.

  11. $request_filename: The full filesystem path of the requested file.

  12. $status: The HTTP response status code (e.g., 200, 404, etc.) that will be sent to the client.

  13. $scheme: The request scheme (e.g., HTTP or HTTPS) used in the request.

  14. $date_local: It s a variable that represents the current local date and time on the server.

Redirect, Rewrite & Try Files

Redirect

An Nginx redirect is a way to inform clients (such as web browsers) that a requested resource has moved to a new location. It involves sending an HTTP response with a specific status code and a Location header pointing to the new URL. This prompts the client to make a new request to the redirected URL.

Redirects are commonly used to ensure that users and search engines are directed to the correct resource, even if its location has changed. There are several types of redirects, each indicated by a different HTTP response status code:

301 Moved Permanently:

  • Status Code: 301

  • Description: This indicates that the requested resource has permanently moved to a new location. It's used when you want search engines and clients to update their bookmarks and caches to the new URL. Subsequent requests for the same resource will automatically be redirected to the new URL.

server {
    listen 80;
    server_name devspace.com;

    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}

In this illustrative Nginx configuration snippet, we're presented with a straightforward yet crucial task—redirecting HTTP traffic to its more secure counterpart, HTTPS, for the domain "devspace.com." The server block, characterized by its listen and server_name directives act as a sentinel for incoming requests on port 80 (HTTP). Its mission is succinct: to redirect visitors to the HTTPS version of the same URL. The magic lies in the return 301 directive, where a permanent redirection (HTTP 301) is orchestrated. By appending https://$host$request_uri, the redirection mechanics are set into motion, seamlessly leading users toward an encrypted and safeguarded browsing experience. Through this elegant maneuver, the server ensures that any users attempting to access the site via HTTP are effortlessly guided to the more secure realm of HTTPS, where data integrity and confidentiality are upheld.

302 Found (HTTP 1.0) / 303 See Other (HTTP 1.1):

  • Status Code: 302 (HTTP 1.0) / 303 (HTTP 1.1)

  • Description: These indicate that the requested resource is temporarily located at a different URL. They are often used for temporary redirects, such as during server maintenance or when implementing A/B testing.

server {
    listen 80;
    server_name devspace.com;

    location /nginx-configuration {
        return 302 /navigating-nginx-a-beginners-guide-to-finding-and-creating-a-basic-web-server;
    }
}

A particular page, originally residing at the lengthy URL "http://devspace.com/nginx-configuration," has been temporarily relocated to a more descriptive and concise location, "http://devspace.com/navigating-nginx-a-beginners-guide-to-finding-and-creating-a-basic-web-server." To ensure a seamless transition for users who may have bookmarked or accessed the old URL, a temporary redirect using the HTTP 302 status code has been employed. This way, when visitors attempt to access the former URL, they are promptly directed to the new location, ensuring continued access to the valuable content. While preserving the essence of a temporary measure, this redirect efficiently guides users to the updated resource, contributing to a smoother browsing experience on the DevSpace website.

307 Temporary Redirect:

  • Status Code: 307

  • Description: Similar to the above, this indicates a temporary redirect. It is used in situations where the client should continue using the original URL for future requests.

  • Difference with 302: Both the 307 and 302 HTTP status codes serve similar purposes, yet their distinction lies in how they handle request headers. In a 302 redirect, the request's HTTP header can be altered, allowing a POST request to be converted to a GET request. In contrast, a 307 redirect maintains the original request method, ensuring that POST requests remain unchanged, thereby preserving the integrity of the initial client request.

server {
    listen 80;
    server_name devspace.com;

    location /send-email {
        return 307 /contact-us;
    }
}

Imagine you're the administrator of "DevSpace," a thriving web platform represented by the domain "devspace.com." In this Nginx configuration snippet, you've crafted a strategic maneuver to enhance user interactions. When users attempt to access the URL path "/send-email" on your site, the server orchestrates a seamless transition using a 307 Temporary Redirect. This clever redirection ensures that visitors are promptly guided to the "/contact-us" page, maintaining the integrity of the original request method, whether it was a GET or POST. This tactical approach ensures that users can effortlessly access the appropriate resources and, in the event of a form submission, retain the data they intended to provide. As you adeptly employ the 307 redirect within the "location" block, you're elevating the user experience by thoughtfully anticipating their needs and facilitating smoother navigation across your virtual domain.

Rewrite

The Nginx rewrite directive is used to alter or modify the requested URL before processing it further. It's a powerful tool for implementing URL redirection, mapping complex URLs to simpler ones, handling specific URL patterns, and more. The rewrite directive is typically placed within a location block in your Nginx configuration.

The syntax of the rewrite directive is as follows:

cssCopy coderewrite regex replacement [flag];
  • regex: A regular expression pattern to match the original URL.

  • replacement: The string to replace the matched portion of the URL.

  • flag (optional): Specifies various options for how the rewrite should be processed. Flags can be combined using a comma.

Here's an explanation of the most commonly used flags with examples:

  1. last Flag:

    • Stops processing and restarts the search for a matching location with the modified URL.

    • Useful for rewriting URLs and then handling them in a different location block.

    location /articles {
        rewrite ^/articles/(.*)$ /posts/$1 last;
    }
  1. break Flag:

    • Stops processing and uses the modified URL as is.

    • Useful for rewriting and internally redirecting within the same location block.

    location /download {
        rewrite ^/download/(.*)$ /files/$1 break;
    }
  1. redirect and permanent Flags:

    • Performs a 302 or 301 HTTP redirection to the modified URL.
    location /old-page {
        rewrite ^/old-page$ /new-page permanent;
    }
  1. redirect Flag:

    • This is used when you want to temporarily redirect the client to a different URL. It returns an HTTP 302 status code along with the new location. The client's browser typically follows the new URL while retaining the original HTTP method (GET, POST, etc.).
    location /old-page {
        rewrite ^/old-page$ /new-page redirect;
    }
  1. last vs. break Comparison:

    • last: Restarts processing and reevaluates the new URL.

    • break: Stops processing and uses the new URL as is.

    • The last and break flags serve a similar purpose when used outside of a location block in Nginx configuration – they both halt the processing of further directives. These flags act as control mechanisms, influencing how Nginx handles the execution flow within the current context.

The rewrite directive in Nginx is a powerful tool for URL manipulation and redirection. However, like any tool, it should be used judiciously based on the specific requirements and considerations of your web application. Here are some scenarios where you should consider using or avoiding the rewrite directive:

When to Use the rewrite Directive:

  1. URL Redirection: When you need to permanently or temporarily redirect one URL to another. This is useful for site restructuring, changing URLs, or handling legacy URLs.

  2. URL Rewriting: When you want to change the structure of the URL to make it more user-friendly, improve SEO, or map complex URLs to simpler ones.

  3. Trailing Slash Handling: When you want to enforce consistency in URL structure by adding or removing trailing slashes.

  4. Query Parameter Handling: When you need to modify URLs based on query parameters, like transforming user input into cleaner URLs.

  5. Multi-Step Processing: When you want to process a request through multiple location blocks, especially with the last flag, to perform different actions at each step.

When to Avoid the rewrite Directive:

  1. Simple Redirections: For basic, standalone redirects, consider using the return directive instead of rewrite to keep configurations cleaner and more efficient.

  2. Complex Rewrites: For very complex URL transformations involving multiple conditions and groups, it might be better to use a dedicated scripting language or a more specialized tool to maintain readability and avoid performance bottlenecks.

  3. Performance Considerations: Excessive or inefficient use of the rewrite directive can impact server performance. Frequent URL rewriting in high-traffic scenarios can lead to unnecessary overhead.

  4. Conditional Redirects: For scenarios involving complex conditions, like redirecting based on specific user agents, using the map directive or another mechanism may provide better readability and maintainability.

  5. File Handling: For serving static files or handling specific file types, it's often more appropriate to use the try_files directive instead of URL rewriting.

Always prioritize readability, maintainability, and performance when deciding whether to use the rewrite directive. Consider using other Nginx directives, such as return, try_files, or location blocks, when they provide a cleaner and more straightforward solution for your specific use case.

Try Files

The try_files directive in Nginx is a powerful tool that simplifies how a web server serves files in response to incoming requests. It allows you to define a sequence of files to try, and Nginx will attempt to serve the first one that exists in the specified order. If none of the files are found, it can optionally fall back to a designated URI or trigger a different action.

The syntax of the try_files directive is as follows:

try_files file ... uri;

Here's a breakdown of the components:

  • file ...: This represents the sequence of files that Nginx will attempt to locate and serve. These files can be specified as relative or absolute paths. You can include multiple files in the sequence, separated by spaces.

  • uri: If none of the specified files are found, Nginx will use the URI specified here for further processing. This can be a local URI, a location block, or even a proxy pass to another backend server.

The try_files directive is commonly used in location blocks to handle various scenarios, such as serving static files, implementing fallbacks, or handling dynamic content generation.

Example 1: Serving Static Files

location /images {
    try_files $uri $uri/ /fallback-image.jpg;
}

In this example, if a request is made to /images/example.jpg, Nginx will attempt to serve that exact file. If it doesn't exist, it will try to serve the directory's index file ($uri/), and if that's also not found, it will serve the fallback-image.jpg file.

Example 2: Fallback to a Different URI

location /downloads {
    try_files $uri /not-found;
}

In this case, if a request is made to /downloads/document.pdf and the file doesn't exist, Nginx will internally redirect the request to the /not-found URI for further processing.

Example 3: Dynamic Content Fallback

location /blog {
    try_files $uri /index.php;
}

Here, if a request is made to /blog/my-article, Nginx will first attempt to locate the corresponding file. If not found, it will rewrite the request to /index.php for processing by a PHP script that can generate the dynamic content.

The try_files directive is a versatile tool that enhances Nginx's ability to serve files and handle requests gracefully. It simplifies the configuration and ensures a smoother user experience by providing alternative paths and fallbacks in case the requested resource is not directly available.

Conclusion

In the intricate realm of Nginx configuration, understanding the foundations of directives and contexts is the gateway to mastering the art of web server orchestration. Directives act as the building blocks of instructions, each carefully sculpted to shape the behavior and functionality of the server. These directives find their homes within contexts, or blocks, creating a hierarchy that reflects the organization and management of the server's configuration.

Through the insightful journey we've embarked upon, we've demystified the powerful rewrite directive. This command wields the capability to transform URLs, redirect traffic, and mold the very essence of how requests are processed. By harnessing its potential within location blocks, administrators can seamlessly steer requests, map intricate URL structures, and provide elegant solutions to complex scenarios.

We've delved into the world of redirection, uncovering the significance of HTTP status codes like 301, 302, and 307. Through practical examples, we've witnessed how the server orchestrates graceful transitions, guiding users to new destinations while preserving the integrity of their interactions.

Yet, it's essential to wield these tools judiciously. As we've explored scenarios to utilize or avoid the rewrite directive, the importance of readability, maintainability, and performance has been consistently emphasized. Just as a maestro skillfully conducts an orchestra, an Nginx administrator must harmonize configurations, ensuring they resonate with the server's intended symphony.

In this intricate dance of directives, contexts, and redirects, we've peeled back layers to reveal the symphonic architecture that underpins Nginx. Armed with this knowledge, you're poised to navigate the labyrinthine paths of configuration, leading your virtual domains to the crescendo of optimal performance, user experience, and security. The stage is set, and the spotlight is yours as you shape the destiny of your web server with the mastery you've cultivated.

1
Subscribe to my newsletter

Read articles from Ritwik Math directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ritwik Math
Ritwik Math

As a seasoned senior web developer with a wealth of experience in Python, Javascript, web development, MySQL, MongoDB, and React, I am passionate about crafting exceptional digital experiences that delight users and drive business success.