Nginx Server Blocks on Ubuntu: Host Multiple Websites

By 

Updated on

5 min read

Set Up Nginx Server Blocks on Ubuntu

If you need to run more than one website on a single server, Nginx server blocks are the way to do it. Each server block defines settings for a specific domain: its own document root, log files, security policy, and SSL certificate. This is the Nginx equivalent of Apache virtual hosts .

This guide walks you through creating Nginx server blocks on Ubuntu, from the directory layout through testing, with two domains as a working example. The steps apply to Ubuntu 22.04, 24.04, and newer releases.

Prerequisites

Before continuing, make sure that:

Creating the Directory Structure

The document root is the directory where the website files for a domain name are stored and served in response to requests. You can set the document root to any location you want. In this example, we will use the following directory structure:

sh
/var/www/
├── domain1.com
│   └── public_html
├── domain2.com
│   └── public_html

Each domain hosted on the server will have its document root set to /var/www/<domain_name>/public_html.

Start by creating the root directory for the domain:

Terminal
sudo mkdir -p /var/www/domain1.com/public_html

Next, create an index.html file and place it in the domain’s root directory. This file will be displayed as the default page when you access the domain URL in your web browser.

/var/www/domain1.com/public_html/index.htmlhtml
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Welcome to domain1.com</title>
  </head>
  <body>
    <h1>Success! domain1.com home page!</h1>
  </body>
</html>

When executing the commands as a sudo user, the newly created files and directories will be owned by the root user. To avoid any permission issues, change the ownership of the domain document root directory and all files within the directory to the Nginx user (www-data) :

Terminal
sudo chown -R www-data: /var/www/domain1.com

Creating a Server Block

Nginx on Ubuntu uses two directories for server block management:

  • /etc/nginx/sites-available/ stores all server block configuration files.
  • /etc/nginx/sites-enabled/ contains symbolic links to the configs that Nginx actually loads.

This separation makes it easy to enable or disable a site without deleting its configuration.

Open your text editor and create the following server block file:

/etc/nginx/sites-available/domain1.comnginx
server {
    listen 80;
    listen [::]:80;

    server_name domain1.com www.domain1.com;

    root /var/www/domain1.com/public_html;

    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    access_log /var/log/nginx/domain1.com.access.log;
    error_log /var/log/nginx/domain1.com.error.log;
}
  • listen 80 and listen [::]:80 accept connections on port 80 for both IPv4 and IPv6.
  • server_name lists the domains that match this server block.
  • root sets the directory from which Nginx serves the domain files.
  • location / matches every request; when a config has several location blocks, the location block match rules decide which one wins.
  • try_files tells Nginx to look for the requested file, then a directory, and return a 404 if neither exists.
  • access_log, error_log set per-site log file locations.

The configuration file can be named anything you want, but it is best to use the domain name for clarity.

Enable the server block by creating a symbolic link to the sites-enabled directory:

Terminal
sudo ln -s /etc/nginx/sites-available/domain1.com /etc/nginx/sites-enabled/

Test the Nginx configuration syntax before applying changes:

Terminal
sudo nginx -t

If there are no errors, the output will look like this:

output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Reload Nginx to apply the new configuration:

Terminal
sudo systemctl reload nginx

Open http://domain1.com in your browser to verify the server block is working. You should see the test page you created earlier:

Adding a Second Domain

Repeat the same steps for each additional domain. Create the document root and a test page:

Terminal
sudo mkdir -p /var/www/domain2.com/public_html
/var/www/domain2.com/public_html/index.htmlhtml
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Welcome to domain2.com</title>
  </head>
  <body>
    <h1>Success! domain2.com home page!</h1>
  </body>
</html>

Set the correct ownership:

Terminal
sudo chown -R www-data: /var/www/domain2.com

Create the server block configuration:

/etc/nginx/sites-available/domain2.comnginx
server {
    listen 80;
    listen [::]:80;

    server_name domain2.com www.domain2.com;

    root /var/www/domain2.com/public_html;

    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }

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

Enable it, test the configuration, and reload:

Terminal
sudo ln -s /etc/nginx/sites-available/domain2.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Both domains are now served from the same server, each with its own files and logs.

Disabling the Default Server Block

Nginx ships with a default server block that displays a welcome page. If you do not remove or disable it, it may respond to requests that do not match any of your configured server_name entries.

To disable it, remove the symbolic link from sites-enabled:

Terminal
sudo rm /etc/nginx/sites-enabled/default

The original configuration file stays in /etc/nginx/sites-available/default, so you can re-enable it later if needed. Reload Nginx to apply the change:

Terminal
sudo systemctl reload nginx

Troubleshooting

The default Nginx page shows instead of your site
Make sure the server_name in your server block matches the domain you are visiting, and that the symbolic link exists in /etc/nginx/sites-enabled/. Also check that the default server block is disabled if it could be catching the request.

“nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)”
Another process is already listening on port 80. Run sudo ss -tlnp | grep :80 to find it. This is usually Apache or another Nginx instance that needs to be stopped first.

Configuration test fails with a syntax error
Run sudo nginx -t to see the exact file and line number. Common causes are missing semicolons, unmatched braces, and typos in directive names.

Conclusion

You now have two domains running on a single Ubuntu server, each with its own Nginx server block, document root, and log files. The same pattern works for any additional domains you need to host. As a next step, consider securing your sites with a free SSL certificate from Let’s Encrypt .

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page