NewHalo Edge 3 is here: HTTP/3 everywhere and 42 edge locations.Learn more
Docs / Web servers

Host multiple sites with nginx server blocks

Web servers8 min readUbuntu 24.04 LTS

One VPS can host many domains. nginx does this with server blocks, where each block claims one or more names with server_name. When a request arrives, nginx compares the requested name, sent in the Host header, with each block and uses the one that matches.

Before you begin

  • nginx installed and running. See Install and configure nginx.
  • Two domains to host. This guide uses example.com and example.org.
  • A sudo user, such as deploy, and the server's IP address, 203.0.113.10.

Step 1: Create a folder for each site

Each site gets its own document root, the folder nginx serves files from. The chown command gives your user ownership so you can edit files without sudo. nginx only needs read access, which the default permissions already allow.

sudo mkdir -p /var/www/example.com/html /var/www/example.org/html
sudo chown -R $USER:$USER /var/www/example.com /var/www/example.org

Step 2: Add a test page to each site

Write a small HTML page into each folder. The > symbol redirects the text into the file, replacing anything already there.

echo "<h1>Welcome to example.com</h1>" > /var/www/example.com/html/index.html
echo "<h1>Welcome to example.org</h1>" > /var/www/example.org/html/index.html

Step 3: Write a server block for each site

Create one file per site in /etc/nginx/sites-available/. Start with example.com by running sudo nano /etc/nginx/sites-available/example.com and entering this:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/example.com/html;
    index index.html;

    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;

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

Create a second file named example.org with the same structure, changing the names and paths to match.

Step 4: Enable the sites

nginx reads only the files linked into sites-enabled. A symbolic link is a shortcut to the original file, so you can enable or disable a site without deleting its config. The last command removes the default site so it does not compete with yours.

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/example.org /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default

Step 5: Test and reload

Check the whole configuration, then reload nginx.

sudo nginx -t
sudo systemctl reload nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Step 6: Test each site by name

Until DNS points both names at your server, use the Host header to pretend you typed the name. Run one request per site:

curl -H "Host: example.com" http://203.0.113.10/
curl -H "Host: example.org" http://203.0.113.10/
<h1>Welcome to example.com</h1>
<h1>Welcome to example.org</h1>
Tip: Keep the names in server_name aligned with your DNS records. Add an A record for each name, including www, in Lantern DNS.

Troubleshooting

  • A request shows the wrong site. Two blocks may claim the same name. Run grep -r server_name /etc/nginx/sites-enabled/ and remove the duplicate.
  • nginx -t reports a duplicate or conflict. Two enabled files use the same listen address and name. Disable one by removing its link in sites-enabled.
  • 403 Forbidden. Usually the folder has no index.html, or nginx cannot read the path. Check with ls -la /var/www/example.com/html.
  • A site is missing from the list. Check the link with ls -l /etc/nginx/sites-enabled/. If it is missing, run the ln -s command again.

Next steps

Once both sites respond, add HTTPS to each domain with Enable HTTPS with free TLS certificates. You can then send all traffic to one address with Redirect HTTP to HTTPS and www to non-www.

Something not working? Chat or email our support team and we will help you get unstuck.

Contact support