> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Intermediate Config introduction

> Practical NGINX guide covering hosting multiple sites, redirects, rewrites, upstream load balancing, reverse proxying, and caching for production.

Welcome back — I hope you had a good break.

In this lesson we explore several practical NGINX features you’ll use regularly in production. We won't cover every option, but we will focus on the most common and useful capabilities:

* Host multiple websites on a single server using `server_name`.
* Perform redirects with `return` (for simple canonicalization like HTTP → HTTPS).
* Rewrite URLs with `rewrite` using regular expressions and capture groups.
* Define `upstream` pools and apply load balancing (round-robin, weighted, least connections, IP hashing).
* Use NGINX as a reverse proxy to forward requests to backend services on other ports.
* Enable caching to improve performance and reduce backend load.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/2df4tIL8w6_cZYgQ/images/Nginx-For-Beginners/Intermediate-Config/Intermediate-Config-introduction/objectives-multiple-sites-redirect-rewrite-urls.jpg?fit=max&auto=format&n=2df4tIL8w6_cZYgQ&q=85&s=fae3d8e58941319b669675dcad8f6461" alt="A slide titled &#x22;Objectives&#x22; with a teal gradient panel on the left. On the right are three numbered goals: hosting multiple sites on one web server, learning to redirect websites, and rewriting friendly URLs." width="1920" height="1080" data-path="images/Nginx-For-Beginners/Intermediate-Config/Intermediate-Config-introduction/objectives-multiple-sites-redirect-rewrite-urls.jpg" />
</Frame>

## Quick overview

Below is a short table summarizing the topics and their typical use cases:

| Feature                        | Use case                                      | Example snippet                                                 |
| ------------------------------ | --------------------------------------------- | --------------------------------------------------------------- |
| Multiple sites (`server_name`) | Host several domains on one server            | See "Hosting multiple sites" section                            |
| Redirects (`return`)           | Simple 301/302 redirections, canonicalization | `return 301 https://$host$request_uri;`                         |
| Rewrites (`rewrite`)           | URL transformations using regex               | `rewrite ^/old/(.*)$ /new/$1 permanent;`                        |
| Upstream pools                 | Group backend servers for proxying            | `upstream backend { server 10.0.0.1:8080; }`                    |
| Load balancing                 | Distribute requests (round-robin, weighted)   | `upstream backend { server a weight=3; server b; }`             |
| Reverse proxy                  | Forward requests (preserve headers)           | `proxy_pass http://backend;`                                    |
| Caching                        | Cache backend responses for performance       | `proxy_cache_path /tmp/cache levels=1:2 keys_zone=mycache:10m;` |

## Hosting multiple sites on one server (server\_name)

NGINX matches requests to a particular server block by listening port and `server_name`. Use separate `server {}` blocks for each domain or subdomain.

Example: two sites on the same IP, one for `example.com` and one for `api.example.com`:

```nginx theme={null}
# site 1
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com/html;
    index index.html;
}

# site 2 (API)
server {
    listen 80;
    server_name api.example.com;
    root /var/www/api.example.com/html;
    index index.html;
}
```

Notes:

* The order of `server_name` matching: exact names, longest wildcard starting with `*`, longest wildcard ending with `*`, then regex.
* Use `listen 443 ssl;` and certificate directives in the HTTPS server block.

<Callout icon="lightbulb" color="#1CB2FE">
  When you add a new domain, create a dedicated `server` block and test the config using `nginx -t` before reloading with `systemctl reload nginx` (or `nginx -s reload`).
</Callout>

## Redirects using `return`

For straightforward redirects (for example redirecting all HTTP traffic to HTTPS or canonicalizing `www`), prefer `return` because it’s simpler and faster than `rewrite`.

HTTP → HTTPS redirect example:

```nginx theme={null}
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}
```

Redirect `www` to non-`www`:

```nginx theme={null}
server {
    listen 80;
    server_name www.example.com;
    return 301 $scheme://example.com$request_uri;
}
```

Use `301` for permanent redirects and `302` for temporary ones.

<Callout icon="warning" color="#FF6B6B">
  Avoid using `rewrite` when a simple `return` covers your use case—`return` is easier to read and slightly more efficient.
</Callout>

## Rewriting URLs with `rewrite` and regex

`rewrite` allows transforming requested URIs using PCRE regular expressions and capture groups. Use it when you need complex mapping (e.g., legacy URL structures -> friendly URLs).

Example: redirect old article paths to a new structure:

```nginx theme={null}
location /old/ {
    rewrite ^/old/([0-9]{4})/([0-9]{2})/(.*)$ /articles/$1/$2/$3 permanent;
}
```

Explanation:

* `^/old/([0-9]{4})/([0-9]{2})/(.*)$` captures year, month, and slug.
* `$1`, `$2`, `$3` reference the captured groups.
* `permanent` issues a 301 redirect.

Tips:

* Test your regex with tools like regex101 to avoid accidental matches.
* Order matters: exact `location` blocks are evaluated before regex `location` blocks. Place regex `location` blocks carefully.

## Upstream pools and load balancing

Use `upstream` blocks to define backend server groups. Reference the group from `proxy_pass` or other proxy directives.

Basic upstream with round-robin (default):

```nginx theme={null}
upstream backend {
    server 10.0.0.10:8080;
    server 10.0.0.11:8080;
}

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

    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
```

Weighted servers:

```nginx theme={null}
upstream backend {
    server 10.0.0.10:8080 weight=3;
    server 10.0.0.11:8080 weight=1;
}
```

Common load balancing methods:

| Algorithm             | Use case                                                                      |
| --------------------- | ----------------------------------------------------------------------------- |
| Round-robin (default) | Simple equal distribution across backends                                     |
| `weight`              | Give more traffic to stronger servers                                         |
| `least_conn`          | Prefer servers with fewer active connections (better for long-lived requests) |
| `ip_hash`             | Sticky sessions by client IP (useful when you don’t have a session store)     |

## Reverse proxy essentials

When proxying, ensure headers and client IPs are passed correctly. The typical minimal proxy configuration includes:

```nginx theme={null}
location / {
    proxy_pass http://backend;
    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;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
}
```

Notes:

* `proxy_http_version 1.1` and clearing `Connection` header help with keepalive behavior to upstreams.
* If your backend runs on a different port, include it in the upstream server definition (e.g., `server 127.0.0.1:3000;`).

## Caching responses with `proxy_cache`

Caching reduces backend load and improves response times. A simple caching setup:

```nginx theme={null}
# define cache storage
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:10m max_size=1g inactive=60m use_temp_path=off;

# server block
server {
    listen 80;
    server_name cache.example.com;

    location / {
        proxy_pass http://backend;
        proxy_cache mycache;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        add_header X-Proxy-Cache $upstream_cache_status;
    }
}
```

Key points:

* `keys_zone` reserves memory for cache keys (e.g., `10m`).
* `proxy_cache_valid` sets caching durations by status code.
* `X-Proxy-Cache` header helps verify whether a response was served from cache (`HIT`) or passed to the backend (`MISS`).

<Callout icon="lightbulb" color="#1CB2FE">
  Design cache keys carefully (including query strings or authentication headers when needed) and have a strategy for cache invalidation. For advanced cache purging, consider modules like `ngx_cache_purge` or manage via short TTLs and revalidation.
</Callout>

## Final notes and best practices

* Always test configuration changes with `nginx -t` and monitor error logs at `/var/log/nginx/error.log`.
* Keep redirect and rewrite rules simple and clearly documented to avoid surprise behavior.
* Use health checks and proper monitoring for upstream backends to detect failures quickly.
* Use HTTPS and HSTS in production; consider automating certificate management with Let’s Encrypt (Certbot) or similar tools.

## Links and references

* [NGINX Documentation — Module ngx\_http\_core\_module](https://nginx.org/en/docs/http/ngx_http_core_module.html)
* [NGINX Docs — Reverse Proxy](https://nginx.org/en/docs/http/ngx_http_proxy_module.html)
* [NGINX Guide — Load Balancing](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/)

This lesson prepares you to host multiple sites, redirect and rewrite URLs, load-balance proxied backends, and cache responses effectively using NGINX.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/nginx-for-beginners/module/c78ff9cb-c15d-4f85-92fc-abee5ed98b20/lesson/4ab9e29b-b87b-47ca-b1dc-0a13b41351ed" />
</CardGroup>
