A single, modest VPS can comfortably host dozens of low-traffic static sites — personal projects, client sites, documentation sites — each on its own domain, using Nginx virtual hosts.
Directory Structure
/var/www/
├── site1.com/html/
├── site2.com/html/
├── site3.com/html/
Step 1 — Create Directories for Each Site
sudo mkdir -p /var/www/site1.com/html
sudo mkdir -p /var/www/site2.com/html
sudo chown -R $USER:$USER /var/www
Step 2 — Create a Server Block Per Domain
sudo nano /etc/nginx/sites-available/site1.com
server {
listen 80;
server_name site1.com www.site1.com;
root /var/www/site1.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Repeat for each additional domain, with its own file and unique server_name/root.
Step 3 — Enable All Sites
sudo ln -s /etc/nginx/sites-available/site1.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/site2.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Step 4 — Point Each Domain's DNS to the VPS
Add an A record for each domain, pointing to the same VPS IP — see How to Point a Domain to Your VPS (A/AAAA Records).
Step 5 — Add SSL for All Domains at Once
sudo certbot --nginx -d site1.com -d www.site1.com -d site2.com -d www.site2.com -d site3.com -d www.site3.com
Certbot detects the corresponding server block for each domain automatically and configures SSL for each.
Automating New Site Creation
sudo nano /usr/local/bin/new-static-site.sh
#!/bin/bash
DOMAIN=$1
mkdir -p /var/www/$DOMAIN/html
echo "<h1>$DOMAIN</h1>" > /var/www/$DOMAIN/html/index.html
cat > /etc/nginx/sites-available/$DOMAIN <<EOF
server {
listen 80;
server_name $DOMAIN www.$DOMAIN;
root /var/www/$DOMAIN/html;
index index.html;
location / {
try_files \$uri \$uri/ =404;
}
}
EOF
ln -s /etc/nginx/sites-available/$DOMAIN /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
echo "Site $DOMAIN created. Point DNS, then run: certbot --nginx -d $DOMAIN -d www.$DOMAIN"
sudo chmod +x /usr/local/bin/new-static-site.sh
sudo new-static-site.sh newsite.com
Isolating Resource Usage Between Sites
Static sites are lightweight enough that resource isolation between them is rarely necessary — unlike dynamic applications, there's no per-site process consuming CPU/RAM continuously.
Monitoring Disk Usage Per Site
du -sh /var/www/*/
Deploying Updates to Individual Sites
rsync -avz --delete ./site1-dist/ deploy@YOUR_SERVER_IP:/var/www/site1.com/html/
See How to Set Up Automatic Static Site Deployment from Git to automate this per site.
Common Errors
Wrong site loads for a domain — verify server_name exactly matches the intended domain in each server block, and that DNS actually points to this server.
SSL certificate request fails for one domain — confirm that specific domain's DNS is correctly configured before including it in the Certbot command; a single failing domain can affect the whole multi-domain request.
Best Practices
- Keep a consistent directory structure across all hosted sites for easier management
- Automate new site setup with a script to reduce manual errors
- Monitor overall disk usage as the number of hosted sites grows
Continue Reading
- How to Host a Static Website on a VPS with Nginx
- Nginx Virtual Hosts: Hosting Multiple Websites
- How to Install Let's Encrypt SSL with Certbot (Nginx & Apache)
Browse more articles in Static Site Hosting & Frontend Deployment.
