Skip to main content

Server Blocks in Nginx: Virtual Hosts for Multiple Sites

Nginx · 29.09.2026

A server block is the Nginx equivalent of an Apache virtual host: a configuration block that describes one site. A single server with one IP address can run dozens of server blocks, and Nginx picks the right one by the Host header of the request. After installing Nginx, as described in the article on installing Nginx on Ubuntu and Debian, the next step is creating the first server block for your domain.

What a server block is and why you need it

Without a server block, Nginx serves every request the same default config from /etc/nginx/sites-enabled/default. As soon as a second site appears on the server, it needs its own server block with a separate document root, logs, and handling rules.

Each server block describes: which port to listen on (listen), which domains it is for (server_name), where the site files live (root), and how to handle different kinds of requests (location directives, covered in detail in the article on location priority in Nginx).

The sites-available and sites-enabled layout

On Ubuntu and Debian, site configurations are conventionally stored in two directories:

  • /etc/nginx/sites-available/ — holds the configuration files for all sites, enabled and disabled.
  • /etc/nginx/sites-enabled/ — holds symbolic links to the active configurations from sites-available.

This split lets you disable a site quickly by removing the symlink without touching the configuration file itself. Creating a new site looks like this:

sudo nano /etc/nginx/sites-available/example.com
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

A minimal server block for one site

A basic configuration for a static site on example.com looks like this:

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com/public;
    index index.html index.php;

    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log;
}

The listen directive sets the port and, if needed, the IP address: listen 192.0.2.10:80 binds the server to only one address. The server_name directive lists domains separated by spaces — Nginx compares them against the Host header of the incoming request.

Several sites on one server

To host a second site, create a separate file in sites-available with a different server_name and its own root. Nginx picks the matching server block by exact server_name match, and if there is no match, it uses the block flagged default_server.

DirectivePurpose
listen 80 default_serverHandles requests with no server_name match
server_name example.comExact domain match
server_name *.example.comMatch by subdomain wildcard
server_name example.com www.example.comSeveral domains for one site

Common mistakes when setting up a server block

A missing default_server on one of the listen 80 blocks is the most common reason Nginx opens the wrong site for a bare IP address without a domain. Only one server block per port can carry the default_server flag; otherwise nginx -t reports a duplicate default server error.

The second common mistake is forgetting to create the symlink in sites-enabled after editing sites-available: the configuration sits on disk, but Nginx does not use it until nginx -t and reload run. HTTPS sites also need an SSL certificate — that process is covered in the article on configuring SSL/TLS in Nginx.

Checking and applying the configuration

After any change to files in sites-available, two commands are mandatory:

  1. sudo nginx -t — checks the syntax of all included configurations at once.
  2. sudo systemctl reload nginx — applies the changes without dropping active connections.

If nginx -t returns an error, systemctl reload changes nothing: Nginx keeps running the old configuration until the error is fixed. That protects a production site from going down over a typo in the config.

A server block is the basic building block of Nginx configuration: one file per site, a clear split between sites-available and sites-enabled, and a mandatory nginx -t check before reload. This foundation supports more advanced scenarios: location rules, reverse proxying, and SSL.

← Back to Knowledge Base Ask Support