Skip to content

🚀 Comprehensive Nginx Tutorial: Common Use Cases & Configurations

Welcome to this comprehensive tutorial on Nginx! Whether you're a beginner or looking to enhance your Nginx skills, this guide covers common use cases, complete with configurations, Mermaid diagrams, and a sprinkle of emojis to make learning fun! 🎉


📚 Table of Contents

  1. Introduction to Nginx 🖥️
  2. Serving Static Files 📄
  3. Reverse Proxy 🔀
  4. Load Balancing ⚖️
  5. SSL Termination 🔒
  6. Gzip Compression 📦
  7. Redirect HTTP to HTTPS 🔄
  8. Custom 404 Error Page ❌
  9. Rate Limiting 🚦
  10. Conclusion 🎉

1. Introduction to Nginx 🖥️

Nginx (pronounced "Engine-X") is a high-performance web server, reverse proxy, load balancer, and HTTP cache. It's renowned for its ability to handle a large number of concurrent connections with low memory usage. 💪

Key Features:

  • Event-driven architecture: Efficient handling of multiple connections.
  • Reverse proxy: Directs client requests to appropriate backend servers.
  • Load balancing: Distributes traffic evenly across servers.
  • SSL/TLS termination: Manages secure connections.
  • Static file serving: Delivers static content swiftly.

Mermaid Diagram: Nginx Architecture

graph LR
    A[Client] -->|HTTP Request| B[Nginx Server]
    B --> C{Reverse Proxy}
    C -->|Server 1| D[Backend Server 1]
    C -->|Server 2| E[Backend Server 2]
    C -->|Server 3| F[Backend Server 3]
    B --> G[Static Files]
    B --> H[SSL/TLS Termination]

2. Serving Static Files 📄

Nginx excels at serving static content like HTML, CSS, JavaScript, images, and videos directly from the file system, ensuring fast and efficient delivery. ⚡

Configuration:

server {
    listen 80;
    server_name example.com;

    location / {
        root /var/www/html;      # Directory containing static files
        index index.html index.htm;
    }

    # Serve specific file types with caching
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;             # Cache these files for 30 days
        add_header Cache-Control "public";
    }
}

Explanation:

  • root: Specifies the directory where your static files are located.
  • index: Defines the default file to serve when accessing the root URL.
  • expires: Sets caching duration for specific file types to improve performance.

3. Reverse Proxy 🔀

A reverse proxy acts as an intermediary for requests from clients seeking resources from servers. It enhances security, scalability, and load distribution. 🌐

Configuration:

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://backend_server:3000;         # Forward requests to backend server
        proxy_set_header Host $host;                    # Preserve original Host header
        proxy_set_header X-Real-IP $remote_addr;        # Pass client IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Mermaid Diagram: Reverse Proxy Flow

sequenceDiagram
    participant Client
    participant Nginx
    participant Backend

    Client->>Nginx: HTTP Request
    Nginx->>Backend: Forward Request
    Backend-->>Nginx: Response
    Nginx-->>Client: Relay Response

Explanation:

  • proxy_pass: Specifies the backend server to which the request should be forwarded.
  • proxy_set_header: Sets or modifies headers to pass client information to the backend.

4. Load Balancing ⚖️

Load balancing distributes incoming network traffic across multiple servers, ensuring no single server becomes a bottleneck. This enhances application reliability and scalability. 🚀

Configuration:

http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        server backend3.example.com;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://backend;                   # Use the upstream group
            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;
        }
    }
}

Load Balancing Methods:

  • Round Robin (Default): Distributes requests evenly across servers.
  • Least Connections: Sends requests to the server with the fewest active connections.
  • IP Hash: Routes requests based on client IP, ensuring the same client always reaches the same server.

Mermaid Diagram: Load Balancing

graph LR
    A[Client] --> B[Nginx Server]
    B --> C1[Backend Server 1]
    B --> C2[Backend Server 2]
    B --> C3[Backend Server 3]

Explanation:

  • upstream: Defines a group of backend servers.
  • proxy_pass: Routes traffic to the defined upstream group for load balancing.

5. SSL Termination 🔒

SSL termination involves handling SSL/TLS encryption at the proxy level, allowing backend servers to communicate over unencrypted channels while ensuring secure client connections. 🔐

Configuration:

server {
    listen 443 ssl;
    server_name secure.example.com;

    ssl_certificate /etc/nginx/ssl/cert.pem;          # Path to SSL certificate
    ssl_certificate_key /etc/nginx/ssl/key.pem;      # Path to SSL private key

    ssl_protocols TLSv1.2 TLSv1.3;                     # Enable secure protocols
    ssl_ciphers HIGH:!aNULL:!MD5;                      # Define secure cipher suites

    location / {
        proxy_pass http://backend_server:3000;         # Forward to backend server
        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;
    }
}

Explanation:

  • ssl_certificate & ssl_certificate_key: Specify the paths to your SSL certificate and private key.
  • ssl_protocols & ssl_ciphers: Define which protocols and ciphers to use for enhanced security.

6. Gzip Compression 📦

Gzip compression reduces the size of responses, leading to faster load times and reduced bandwidth usage. It's particularly effective for compressing text-based content like HTML, CSS, and JavaScript. 📉

Configuration:

http {
    gzip on;                                         # Enable gzip compression
    gzip_disable "msie6";                            # Disable for old browsers

    gzip_vary on;                                    # Enable Vary header for proxies
    gzip_proxied any;                                # Compress all proxied requests
    gzip_comp_level 5;                               # Compression level (1-9)
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_min_length 256;                             # Minimum length of response to compress
}

Explanation:

  • gzip on: Activates gzip compression.
  • gzip_types: Specifies the MIME types to compress.
  • gzip_comp_level: Determines the compression level (higher means more compression but more CPU usage).

7. Redirect HTTP to HTTPS 🔄

Forcing HTTPS ensures that all communication between clients and your server is encrypted, enhancing security. This is a common best practice in web development. 🔐

Configuration:

server {
    listen 80;
    server_name example.com;

    return 301 https://$host$request_uri;              # Permanent redirect to HTTPS
}

Explanation:

  • return 301: Sends a permanent redirect response to clients, directing them to the HTTPS version of the requested URL.

Mermaid Diagram: HTTP to HTTPS Redirection

sequenceDiagram
    participant Client
    participant Nginx

    Client->>Nginx: HTTP Request
    Nginx-->>Client: 301 Redirect to HTTPS
    Client->>Nginx: HTTPS Request
    Nginx->>Backend: Forward HTTPS Request
    Backend-->>Nginx: Response
    Nginx-->>Client: Secure Response

8. Custom 404 Error Page ❌

Custom error pages improve user experience by providing informative and branded responses when something goes wrong. 🎨

Configuration:

server {
    listen 80;
    server_name example.com;

    error_page 404 /custom_404.html;

    location /custom_404.html {
        root /var/www/html;                          # Directory containing custom 404 page
        internal;                                    # Prevent direct access
    }

    location / {
        try_files $uri $uri/ =404;                   # Attempt to serve requested file or return 404
    }
}

Explanation:

  • error_page 404: Specifies the path to the custom 404 error page.
  • internal: Ensures that the custom error page cannot be accessed directly by clients.

Custom 404 HTML (/var/www/html/custom_404.html):

<!DOCTYPE html>
<html>
  <head>
    <title>Page Not Found</title>
    <style>
      body {
        text-align: center;
        padding: 50px;
        font-family: Arial, sans-serif;
      }
      h1 {
        font-size: 50px;
      }
      p {
        font-size: 20px;
      }
      a {
        color: #3498db;
        text-decoration: none;
      }
    </style>
  </head>
  <body>
    <h1>404</h1>
    <p>Oops! The page you're looking for doesn't exist.</p>
    <a href="/">Go Back Home</a>
  </body>
</html>

9. Rate Limiting 🚦

Rate limiting controls the number of requests a client can make in a given timeframe, protecting your server from abuse and ensuring fair usage. 🛡️

Configuration:

http {
    # Define the rate limit zone
    limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;

    server {
        listen 80;
        server_name example.com;

        location / {
            limit_req zone=one burst=10 nodelay;       # Apply rate limiting
            proxy_pass http://backend_server:3000;     # Forward to backend server
            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;
        }

        # Optional: Custom rate limit exceeded message
        error_page 429 /rate_limit_exceeded.html;
        location = /rate_limit_exceeded.html {
            root /var/www/html;
            internal;
        }
    }
}

Explanation:

  • limit_req_zone: Defines a shared memory zone for rate limiting, based on the client's IP address.
  • limit_req: Applies the rate limit to the specified zone within the location block.
  • burst: Allows a certain number of excess requests before enforcing the rate limit.
  • nodelay: Ensures that excess requests are rejected immediately without delay.

Custom 429 Error Page (/var/www/html/rate_limit_exceeded.html):

<!DOCTYPE html>
<html>
  <head>
    <title>Too Many Requests</title>
    <style>
      body {
        text-align: center;
        padding: 50px;
        font-family: Arial, sans-serif;
      }
      h1 {
        font-size: 50px;
        color: red;
      }
      p {
        font-size: 20px;
      }
      a {
        color: #3498db;
        text-decoration: none;
      }
    </style>
  </head>
  <body>
    <h1>429</h1>
    <p>Too Many Requests. Please try again later.</p>
    <a href="/">Go Back Home</a>
  </body>
</html>

10. Conclusion 🎉

Congratulations! 🎊 You've now explored some of the common use cases of Nginx and learned how to configure it for various scenarios:

  • Serving Static Files 📄
  • Reverse Proxy 🔀
  • Load Balancing ⚖️
  • SSL Termination 🔒
  • Gzip Compression 📦
  • Redirect HTTP to HTTPS 🔄
  • Custom 404 Error Page
  • Rate Limiting 🚦

Final Tips:

  • Security First: Always keep your Nginx and backend servers updated. Regularly review your configurations for security best practices.
  • Monitor Performance: Use tools like Nginx Amplify, Prometheus, or Grafana to monitor your server's performance and health.
  • Optimize Configurations: Tailor your Nginx settings based on your application's specific needs to achieve optimal performance.

Additional Resources 📖