Host multiple sites with nginx server blocks
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>
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 withls -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 theln -scommand 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