> ## 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

> An intermediate NGINX configuration guide covering virtual hosts, redirects, URL rewriting, upstreams, load balancing, reverse proxying, caching, testing, and best practices for production deployments

Welcome back — I hope you had a good break.

This guide explores several of NGINX’s most useful features. We won't document every capability; instead we'll focus on the patterns you'll use most frequently in production. The topics are presented in a logical order so you can follow along and build on each concept.

Throughout this guide we will validate configuration syntax with `nginx -t` and reload NGINX after changes (for example `systemctl reload nginx` or `nginx -s reload`) so your edits can be tested safely without downtime.

Overview of topics

* Hosting multiple websites (virtual hosts)
  * How NGINX maps requests to server blocks using the `server_name` directive.
  * Matching strategies and priority rules (exact names, wildcards, and regex).
* Redirects
  * Using the `return` directive for simple, efficient redirects (for example, redirecting HTTP to HTTPS).
* URL rewriting
  * The `rewrite` directive and basic regular expressions for routing and URL manipulation.
  * Examples illustrating capture groups and common rewrite patterns.
* Upstreams
  * Defining `upstream` blocks to group backend servers into a single logical pool for proxying.
  * How upstreams integrate with `proxy_pass`.
* Load balancing
  * How NGINX distributes traffic across upstream backends.
  * Built-in algorithms such as `round-robin` (default), `least_conn`, and weighted servers.
* Reverse proxying
  * Using NGINX as a reverse proxy to forward requests to backend services (often running on different ports like `8080`, `3000`, etc.).
  * Handling headers, timeouts, and connection settings for robust proxying.
* Caching
  * Why caching improves performance and reduces backend load.
  * Basic `proxy_cache` building blocks and configuration examples.

Below are concise examples, best-practice suggestions, and quick tests to help you apply these patterns reliably.

Quick reference table — common directives and use cases

| Directive / Block | Use case | Example snippet |
| - | -: | - |
| `server_name` | Map Host header to a server block | `server { server_name example.com www.example.com; }` |
| `return` | Simple redirects (fast, no rewrite parsing) | `return 301 https://$host$request_uri;` |
| `rewrite` | Advanced URL transformations with regex | `rewrite ^/old/(.*)$ /new/$1 permanent;` |
| `upstream` | Group backend servers for proxying/load balancing | `upstream backend { server 10.0.0.10:8080; }` |
| `proxy_pass` | Forward requests to upstream or backend URL | `proxy_pass http://backend;` |
| `proxy_cache` | Cache backend responses at the proxy layer | `proxy_cache my_cache; proxy_cache_valid 200 1h;` |

1. Hosting multiple websites (virtual hosts)

NGINX uses server blocks to host multiple websites on a single machine. The `server_name` directive is the primary mapping between an incoming Host header and a server block. Priority rules are: exact names > longest wildcard starting with \* > longest wildcard ending with \* > regex matches.

Example: two sites on one server (port 80)

```nginx theme={null}
# /etc/nginx/conf.d/sites.conf
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

server {
    listen 80;
    server_name blog.example.com;
    root /var/www/blog/html;
    index index.html;
}
```

Tips:

* Use `listen 80 default_server` only for a fallback.
* For HTTPS you’ll add `listen 443 ssl` and TLS certs per server block.

2. Redirects

When you need a simple redirect (HTTP→HTTPS, domain canonicalization, etc.), use `return`. It's fast and clear.

Example: redirect all HTTP to HTTPS

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

Example: canonical domain redirect

```nginx theme={null}
server {
    listen 443 ssl;
    server_name www.example.com;
    return 301 https://example.com$request_uri;
    # ssl_certificate /etc/...
}
```

3. URL rewriting

Use `rewrite` for regex-based URL transformations or legacy URL patterns. For many routing cases, consider `try_files` first (it's less error-prone and faster).

Examples: rewrite with capture groups

```nginx theme={null}
# Permanent rewrite from /old/path/anything -> /new/path/anything
location /old/path/ {
    rewrite ^/old/path/(.*)$ /new/path/$1 permanent;
}
```

Example: simple internal rewrite (no redirect)

```nginx theme={null}
location /docs/ {
    rewrite ^/docs/([0-9]+)/?$ /docs.php?id=$1 last;
}
```

Note:

* `last` stops processing the current location and restarts the location lookup.
* `break` stops processing rewrite directives in the current location and serves the rewritten URI.

4. Upstreams

Group backends into `upstream` blocks and reference them via `proxy_pass`. This centralizes backend definitions and enables load-balancing options.

Example: a basic upstream with three backends

```nginx theme={null}
upstream app_backend {
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
    server 10.0.0.13:8080;
}
```

Using the upstream in a server block:

```nginx theme={null}
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://app_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;
    }
}
```

5. Load balancing

NGINX supports several built-in algorithms. Default is round-robin.

| Algorithm | When to use | Configuration example |
| - | - | - |
| `round-robin` (default) | Most general use cases | `upstream u { server a; server b; }` |
| `least_conn` | Backends with variable request cost | `upstream u { least_conn; server a; server b; }` |
| weights | Favor some servers over others | `upstream u { server a weight=3; server b weight=1; }` |

Health checks are available in commercial/NGINX Plus and via third-party modules for open source; you can also implement passive checks (detect failures from backend responses/timeouts).

6. Reverse proxying — headers, timeouts, and robust proxying

Use `proxy_pass` to forward requests. Configure connection and response timeouts plus buffering for reliability.

Example: common proxy settings

```nginx theme={null}
location / {
    proxy_pass http://app_backend;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    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_connect_timeout 5s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;

    proxy_buffering on;
    proxy_buffers 16 4k;
    proxy_busy_buffers_size 8k;
}
```

When proxying WebSockets, include `proxy_http_version 1.1` and forward connection headers.

7. Caching

Caching reduces backend load and improves latency. Basic building blocks: `proxy_cache_path`, `proxy_cache`, `proxy_cache_key`, and `proxy_cache_valid`.

Example: basic file-based cache

```nginx theme={null}
# global http{} scope
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";

server {
    location / {
        proxy_pass http://app_backend;
        proxy_cache my_cache;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;
        add_header X-Cache-Status $upstream_cache_status;
    }
}
```

Common headers:

* `X-Cache-Status` or `X-Cache` help you diagnose caching behavior (`HIT`, `MISS`, `BYPASS`, etc.).
* Respect `Cache-Control` and `Expires` from upstream if desired (use `proxy_ignore_headers` to override).

Testing and validating changes

* Check syntax: `nginx -t`
* Reload gracefully: `systemctl reload nginx` or `nginx -s reload`
* Inspect logs: `/var/log/nginx/access.log` and `/var/log/nginx/error.log`
* Use curl to validate behavior:

```bash theme={null}
curl -I http://example.com        # check redirects and headers
curl -I -H "Host: example.com" http://<nginx-ip>  # test server_name matching
```

Links and references

* NGINX official docs: [https://nginx.org/en/docs/](https://nginx.org/en/docs/)
* NGINX HTTP proxy module: [https://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html](https://nginx.org/en/docs/http/ngx_http_proxy_module.html)
* NGINX rewrite module: [https://nginx.org/en/docs/http/ngx\_http\_rewrite\_module.html](https://nginx.org/en/docs/http/ngx_http_rewrite_module.html)
* Guide to NGINX caching: [https://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_cache](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache)

Final notes

* Prefer `return` and `try_files` for simple, performant operations before reaching for `rewrite`.
* Keep upstream definitions centralized so you can manage backends and weights without editing many server blocks.
* Add health checks, timeouts, and appropriate headers to make proxying resilient.
* Always validate with `nginx -t` and reload gracefully to avoid downtime.

> **[Watch Video](https://learn.kodekloud.com/user/courses/nginx-for-beginners/module/c78ff9cb-c15d-4f85-92fc-abee5ed98b20/lesson/4ab9e29b-b87b-47ca-b1dc-0a13b41351ed)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.