WEB SERVER
June 23, 2026

How to Set Up Nginx Server Blocks (Virtual Hosts)

8 min read
Author
CloudStick Team
Security Specialist
Share this article
Nginx Server Blocks
CloudStick
Nginx Server Blocks

What Are Nginx Server Blocks?

An Nginx server block is equivalent to Apache's VirtualHost directive — it maps a domain name to a specific directory on your server and defines how Nginx should handle requests for that domain. You can run dozens of websites on a single VPS, each with its own server block pointing to a different document root, PHP version, and access log.

Nginx loads server blocks from config files in /etc/nginx/sites-available/ that are symlinked into /etc/nginx/sites-enabled/. This two-directory pattern lets you maintain site configs without activating them — remove the symlink to disable, restore it to re-enable, without deleting the config file.

Create the Directory Structure

Each website gets its own directory under /var/www/. Separating sites this way isolates their files and makes permission management clean — each site can have its own system user, preventing one compromised site from reading another's files.

# Create web root for each domain
sudo mkdir -p /var/www/example.com/public
sudo mkdir -p /var/www/anotherdomain.com/public
# Set ownership to the web user (or your deploy user)
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
# Create a test index page
echo "<h1>example.com is working</h1>" | sudo tee /var/www/example.com/public/index.html

Write the Server Block Config

Create a config file for each domain in sites-available. Name the file after your domain for easy identification. The server block below handles a PHP site with WordPress-compatible URL rewriting and separates access logs per site.

sudo nano /etc/nginx/sites-available/example.com
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.php index.html index.htm;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}

Enable the Site with a Symlink

Nginx does not read files from sites-available directly — it only reads sites-enabled. Activate the config by creating a symlink. Then remove the default site to prevent Nginx from serving the welcome page on your domain.

# Create symlink to activate the site
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# Disable the default site (optional but recommended)
sudo rm /etc/nginx/sites-enabled/default

Test and Reload Nginx

Always validate the configuration before reloading. nginx -t checks every included config file and reports syntax errors with the file name and line number. If it passes, reload gracefully — active connections are not dropped during a reload.

# Test configuration syntax
sudo nginx -t
# Expected output:
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
# Reload Nginx (graceful — no downtime)
sudo systemctl reload nginx
WARNING

Never use systemctl restart nginx in production — it tears down all active connections. Use systemctl reload nginx instead. It applies the new config without dropping connections. Only use restart if Nginx fails to start after a crash.

Managing Multiple Sites at Scale

For agencies managing 10, 20, or 50 sites on a single server, manually creating and maintaining Nginx server blocks becomes error-prone. CloudStick automates exactly this workflow — when you add a new website through the CloudStick dashboard, it creates the directory structure, writes the server block, handles the symlink, and reloads Nginx automatically.

Each site also gets an isolated PHP-FPM pool, separate access logs, and its own system user. This is the correct multi-tenant server architecture — and it is the default for every site created through CloudStick. For a single-server agency workflow, the dashboard approach eliminates an entire class of configuration mistakes.

Leave a comment
Full Name
Email Address
Message
Contents

We use cookies to improve your experience

CloudStick uses cookies to personalise content, analyse traffic and keep you signed in. Cookie Policy · Terms of Service

Manage cookies