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

# Demo Configure Multiple Sites

> How to configure Nginx host based virtual hosting to serve multiple websites, create site configs, enable sites, and test using curl with custom Host headers

In this lesson you'll configure Nginx to host two different websites on the same server using host-based virtual hosting. Nginx inspects the HTTP `Host` header and routes requests to the matching `server` block (site). We'll create two site configs (example1 and example2), enable them, and test using `curl` with a custom `Host` header.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/2df4tIL8w6_cZYgQ/images/Nginx-For-Beginners/Intermediate-Config/Demo-Configure-Multiple-Sites/configure-multiple-sites-demo-slide.jpg?fit=max&auto=format&n=2df4tIL8w6_cZYgQ&q=85&s=bfd7283890158d70cfff9a4e8df32a98" alt="A presentation slide that reads &#x22;Configure Multiple Sites&#x22; on the left and shows a teal gradient shape on the right with the word &#x22;Demo.&#x22; The bottom-left corner includes &#x22;© Copyright KodeKloud.&#x22;" width="1920" height="1080" data-path="images/Nginx-For-Beginners/Intermediate-Config/Demo-Configure-Multiple-Sites/configure-multiple-sites-demo-slide.jpg" />
</Frame>

## Overview

* Client (browser or `curl`) sends an HTTP request to the server.
* Nginx reads the `Host` header and selects the `server` block with a matching `server_name`.
* If no match is found, Nginx serves the default server for that address/port (the first matching server block).

## Initial state — remove the default site

Remove the default site so it doesn't interfere with our example sites, then reload Nginx:

```bash theme={null}
# remove the default symlink (or file) from sites-enabled and reload
root@ubuntu-host:/etc/nginx/sites-enabled# rm default
root@ubuntu-host:/etc/nginx/sites-enabled# nginx -s reload
root@ubuntu-host:/etc/nginx/sites-enabled# curl localhost
curl: (7) Failed to connect to localhost port 80: Connection refused
```

Explanation: after removing the default server block that listened on port 80, Nginx no longer has a listener for that address/port. Connections to `localhost:80` are refused until you enable a site that listens on port 80.

<Callout icon="warning" color="#FF6B6B">
  Removing the default site will stop responses on port 80 until at least one valid site is enabled. Ensure you add and enable your site configurations before relying on the server in production.
</Callout>

## Create site configurations

1. Copy the default configuration to use as a template for `example1`, then edit it:

```bash theme={null}
root@ubuntu-host:/etc/nginx/sites-available# cp default example1
root@ubuntu-host:/etc/nginx/sites-available# vim example1
```

A minimal, cleaned `server` block for `example1`:

```nginx theme={null}
server {
    listen 80;
    root /var/www/example1;
    index index.html index.htm;
    server_name www.example1.com;

    location / {
        # try_files will check each option in order and return 404 if none match
        try_files $uri $uri/ =404;
    }
}
```

Notes:

* `try_files` attempts to serve a file or directory; if nothing matches, it returns a 404.
* Use a dedicated `root` directory per site to avoid accidentally serving `/var/www/html` content.

2. Create `example2` by copying `example1` and updating `root` and `server_name`:

```bash theme={null}
root@ubuntu-host:/etc/nginx/sites-available# cp example1 example2
# Edit example2 and change:
# root /var/www/example2;
# server_name www.example2.com;
```

## Prepare site content

Create site directories and simple `index.html` pages:

```bash theme={null}
root@ubuntu-host:~# mkdir -p /var/www/example1 /var/www/example2

root@ubuntu-host:~# cat > /var/www/example1/index.html <<'HTML'
<h1>Example 1!!!</h1>
HTML

root@ubuntu-host:~# cat > /var/www/example2/index.html <<'HTML'
<h1>Example 2!!!</h1>
HTML
```

## Enable the sites, validate, and reload

Create symlinks in `sites-enabled`, validate the configuration, and reload Nginx:

```bash theme={null}
root@ubuntu-host:/etc/nginx/sites-available# ln -s /etc/nginx/sites-available/example1 /etc/nginx/sites-enabled/example1
root@ubuntu-host:/etc/nginx/sites-available# ln -s /etc/nginx/sites-available/example2 /etc/nginx/sites-enabled/example2

# Validate and reload
root@ubuntu-host:/etc/nginx/sites-available# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

root@ubuntu-host:/etc/nginx/sites-available# nginx -s reload
```

## Test using curl with a Host header

Simulate requests for different domains by setting the `Host` header with `curl`:

```bash theme={null}
root@ubuntu-host:/etc/nginx/sites-available# curl --header "Host: www.example1.com" localhost
<h1>Example 1!!!</h1>

root@ubuntu-host:/etc/nginx/sites-available# curl --header "Host: www.example2.com" localhost
<h1>Example 2!!!</h1>

# If the Host header doesn't match any server_name, Nginx serves the first matching server block
root@ubuntu-host:/etc/nginx/sites-available# curl --header "Host: anything.com" localhost
<h1>Example 1!!!</h1>
```

Quick mapping reference:

| Request Host header | Served content                                        |
| ------------------- | ----------------------------------------------------- |
| `www.example1.com`  | `Example 1` page                                      |
| `www.example2.com`  | `Example 2` page                                      |
| any other host      | First enabled server block (`example1` in this setup) |

Behavior detail:

* When no `server_name` matches the `Host` header, Nginx falls back to the default server for that address/port. With multiple enabled files, the fallback is typically the first server block encountered (often determined by alphabetical order of files in `/etc/nginx/sites-enabled`).

## Alternative: multiple server blocks in one file

You can place multiple `server { ... }` blocks in a single configuration file. Example:

```nginx theme={null}
server {
    listen 80;
    root /var/www/example1;
    index index.html index.htm;
    server_name www.example1.com;
    location / {
        try_files $uri $uri/ =404;
    }
}

server {
    listen 80;
    root /var/www/example2;
    index index.html index.htm;
    server_name www.example2.com;
    location / {
        try_files $uri $uri/ =404;
    }
}
```

Operational considerations:

* If both sites are in the same file and that file is deleted or misconfigured, both sites will be affected.
* Best practice: keep one site per file in `/etc/nginx/sites-available` and enable sites with symlinks in `/etc/nginx/sites-enabled` to limit the blast radius and simplify rollbacks.

## Final reminders

* Always run `nginx -t` after editing configuration files to validate syntax.
* After a successful test, reload Nginx with `nginx -s reload` to apply changes.
* Creating/editing files under `/etc/nginx/sites-available` alone does not activate a site — remember to create corresponding symlinks in `/etc/nginx/sites-enabled`.

<Callout icon="lightbulb" color="#1CB2FE">
  Keep each site's configuration separate (one file per site) and use symlinks in `/etc/nginx/sites-enabled` for better isolation and safer rollbacks.
</Callout>

That's it for this lesson.

## Links and references

* [Nginx documentation — Server names](https://nginx.org/en/docs/http/server_names.html)
* [Nginx documentation — try\_files directive](https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files)

<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/db98f13e-91c5-43d1-9400-fd40daf84b42" />

  <Card title="Practice Lab" icon="flask-conical" cta="Learn more" href="https://learn.kodekloud.com/user/courses/nginx-for-beginners/module/c78ff9cb-c15d-4f85-92fc-abee5ed98b20/lesson/c74f891f-6063-47cc-8144-ada26fef3e78" />
</CardGroup>
