What Are Nginx Virtual Hosts?
Nginx uses server blocks (analogous to Apache's virtual hosts) to serve multiple websites from a single server instance. By configuring separate server blocks for each domain, you can host dozens or hundreds of websites on one machine, each with its own document root, SSL certificate, and configuration — a fundamental requirement for any web hosting setup.
Prerequisites
- A Linux server (Ubuntu 22.04 or Debian 12 recommended for this guide)
- Nginx installed:
sudo apt update && sudo apt install nginx - A domain name with DNS A records pointing to your server's IP
- Root or sudo access
Step 1: Create the Document Root
Create a directory to hold your website files. Replace example.com with your actual domain:
sudo mkdir -p /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/example.com/html
sudo chmod -R 755 /var/www/example.com
Create a simple test page to confirm the setup works:
echo "<h1>Welcome to example.com</h1>" > /var/www/example.com/html/index.html
Step 2: Create the Server Block Configuration File
Nginx configuration files live in /etc/nginx/sites-available/. Create a new file for your domain:
sudo nano /etc/nginx/sites-available/example.com
Add the following configuration:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm index.php;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ =404;
}
}
Key directives explained:
- listen 80 / [::]:80: Listen on IPv4 and IPv6 for HTTP traffic
- server_name: The domain(s) this block responds to
- root: The document root directory
- try_files: Attempts to serve the requested file, then directory, then returns 404
Step 3: Enable the Site
Nginx uses a symlink pattern — configurations in sites-available are enabled by linking them to sites-enabled:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Test the configuration for syntax errors before reloading:
sudo nginx -t
If the test passes, reload Nginx:
sudo systemctl reload nginx
Step 4: Add SSL with Let's Encrypt
Serve your site over HTTPS using a free Let's Encrypt certificate via Certbot:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
Certbot will automatically modify your server block to add HTTPS directives and set up automatic renewal.
Step 5: Hosting Multiple Sites
To host additional domains, repeat Steps 1–3 for each domain. Each site gets its own configuration file, document root, and log files. The default Nginx server block (in sites-enabled/default) should be disabled to prevent conflicts:
sudo rm /etc/nginx/sites-enabled/default
Troubleshooting Common Issues
- 403 Forbidden: Check directory permissions — Nginx's worker process needs read access to the document root
- 502 Bad Gateway: Usually a PHP-FPM issue — verify the PHP socket path in your config matches the running socket
- Conflicting server_name: Two server blocks with the same domain will cause unpredictable behavior — audit with
nginx -T | grep server_name - Changes not taking effect: Always run
sudo systemctl reload nginx(not restart) after config changes in production
Summary
Setting up Nginx virtual hosts is a straightforward but foundational skill for anyone managing web servers. The server block pattern scales cleanly from a single site to hundreds of hosted domains, and combined with Let's Encrypt automation, gives you a robust, cost-effective hosting stack.