Skip to content

nginx

Ah, now you want Nginx to serve multiple websites (virtual hosts) from the same server — each with its own domain name and directory. This is called name-based virtual hosting. Here’s how to do it step by step.


Suppose you have 2 sites:

DomainRoot folder
site1.example.com/var/www/site1
site2.example.com/var/www/site2

Create the directories:

Terminal window
sudo mkdir -p /var/www/site1
sudo mkdir -p /var/www/site2

Add a test file in each:

Terminal window
echo "Hello from Site 1" | sudo tee /var/www/site1/index.html
echo "Hello from Site 2" | sudo tee /var/www/site2/index.html

Set ownership and permissions:

Terminal window
sudo chown -R www-data:www-data /var/www/site1 /var/www/site2
sudo chmod -R 755 /var/www/site1 /var/www/site2

2️⃣ Create server blocks for each site

Section titled “2️⃣ Create server blocks for each site”
sudo nano /etc/nginx/sites-available/site1.conf
server {
listen 80;
listen [::]:80;
server_name site1.example.com;
root /var/www/site1;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
sudo nano /etc/nginx/sites-available/site2.conf
server {
listen 80;
listen [::]:80;
server_name site2.example.com;
root /var/www/site2;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}

Terminal window
sudo ln -s /etc/nginx/sites-available/site1.conf /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/site2.conf /etc/nginx/sites-enabled/

Test Nginx config:

Terminal window
sudo nginx -t
sudo systemctl reload nginx

Both domains must point to your server’s IP:

  • site1.example.com → <server-IP>
  • site2.example.com → <server-IP>

5️⃣ Optional: HTTPS with Let’s Encrypt

Section titled “5️⃣ Optional: HTTPS with Let’s Encrypt”
Terminal window
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d site1.example.com -d site2.example.com

Certbot can automatically configure HTTPS for multiple sites.


6️⃣ Optional: Serve multiple directories on different ports

Section titled “6️⃣ Optional: Serve multiple directories on different ports”

You can also assign different ports:

server {
listen 82;
server_name site1.example.com;
root /var/www/site1;
index index.html;
}
server {
listen 83;
server_name site2.example.com;
root /var/www/site2;
index index.html;
}

But in practice, name-based hosting on port 80/443 is preferred, because clients don’t need to type the port.


  • Each server_name gets its own root folder.
  • You can combine with reverse proxy to point some domains to backend apps.
  • Nginx automatically picks the server block based on the Host header.

If you want, I can create a ready-to-copy Nginx configuration for 3+ domains with both static files and reverse proxy backends, all HTTPS-enabled, so you don’t have to modify anything manually.

Do you want me to do that?

Perfect! Let’s create a ready-to-use Nginx configuration that handles multiple domains, each with its own directory or backend, and HTTPS enabled.

I’ll assume:

  • 3 domains for example:

    • site1.evolo.fr → static files in /var/www/site1
    • site2.evolo.fr → static files in /var/www/site2
    • site3.evolo.fr → backend app (Node.js/Python) on 127.0.0.1:3000
  • You want automatic HTTPS via Let’s Encrypt


Terminal window
sudo mkdir -p /var/www/site1 /var/www/site2
sudo chown -R www-data:www-data /var/www/site1 /var/www/site2
sudo chmod -R 755 /var/www/site1 /var/www/site2
# Add test pages
echo "Hello from Site 1" | sudo tee /var/www/site1/index.html
echo "Hello from Site 2" | sudo tee /var/www/site2/index.html

Create a single config file for all 3 sites:

Terminal window
sudo nano /etc/nginx/sites-available/multi-sites.conf

Paste:

# ------------------------
# Site 1: Static
# ------------------------
server {
listen 80;
listen [::]:80;
server_name site1.evolo.fr;
root /var/www/site1;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
# ------------------------
# Site 2: Static
# ------------------------
server {
listen 80;
listen [::]:80;
server_name site2.evolo.fr;
root /var/www/site2;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
# ------------------------
# Site 3: Backend app
# ------------------------
server {
listen 80;
listen [::]:80;
server_name site3.evolo.fr;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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_cache_bypass $http_upgrade;
}
}

Terminal window
sudo ln -s /etc/nginx/sites-available/multi-sites.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Terminal window
sudo apt install certbot python3-certbot-nginx
# For all 3 domains at once
sudo certbot --nginx -d site1.evolo.fr -d site2.evolo.fr -d site3.evolo.fr

Certbot will:

  • Create HTTPS server blocks
  • Redirect HTTP → HTTPS automatically
  • Configure SSL certificates

If needed, add this server block before the others:

server {
listen 80;
listen [::]:80;
server_name site1.evolo.fr site2.evolo.fr site3.evolo.fr;
return 301 https://$host$request_uri;
}

  • Each domain has its own folder or backend
  • HTTPS enabled automatically
  • Works for static sites or reverse-proxied apps
  • Easy to add more sites: just create a new server {} block

I can also make a fully ready template for 5+ domains with both static and dynamic backends, including directory listing disabled, caching, and compression, so it’s production-ready.

Do you want me to do that?