How to Create Nginx Virtual Host (Server Block)

Server blocks, often called virtual hosts in Nginx, allow you to host multiple websites on a single server. Here's how to use them!

Nginx is designed to handle multiple domains on a single server and IP address. In other words, if you have a server that is used as a web server and allocated one IP address only, then you need to use Nginx virtual hosts to have more than one website or domain running on the server.

Before you begin this tutorial, you’ll need to install Nginx. To learn how to install it, read our excellent guide on Installing Nginx Web Server on Linux.

What is a Virtual Host?

Let me explain if you’re not sure what a virtual host is. It is an Apache HTTP Server term; however, it is also commonly used by Nginx users. The proper term for Nginx is server block.

Related: Apache vs. Nginx: Which Web Server You Should Choose

In short, a virtual host is a method for hosting multiple domain names on a single server.

How Does Virtual Host Work?

When you start web server software like Nginx on a server, that web server will bind itself to one or more network ports. Usually, for a web server, that will be ports 80 and 443.

When a computer goes to visit a website, it will send a request over the internet to the server, and the server will receive that request. But, first, the server will look at the destination port to which the request was sent.

Next, it will use that destination port to determine the application to which to forward that information. That means your web server can only have one application receiving the requests.

But what if you want to run two websites on the same server? When a packet requesting a website is received, the server must determine which website is being requested before deciding what information to return.

It is essential to understand that no matter what website is requested, the server cannot identify which website a client is trying to access based on the port number and destination port.

So all the server will do is say, “I’m sending this request to Nginx.” From there, Nginx has to decide what to send back.

This is when the server blocks come into play. They can be used to serve other websites based on the IP address requested or to serve different websites based on the domain name used.

How Does Nginx Virtual Host Works

So, when you type in a website’s name, such as www.example.com, and the server receives it, Nginx will look into the HTTP headers to see what server name was requested.

Then, based on the virtual hosts configured, the server determines which directory stores the website files and delivers the correct response to the client based on the server name.

How to Create Nginx Virtual Hosts (Server Blocks)

We can create and store our virtual host configuration files in two directories. Both of them are located inside the /etc/nginx directory. The names of those two directories are sites-available and sites-enabled.

  • /etc/nginx/sites-available: The directory where individual virtual hosts (websites) are defined. Remember that Nginx will not use the configuration files in this directory unless they are linked to the /etc/nginx/sites-enabled directory.
  • /etc/nginx/sites-enabled: List of the virtual hosts (websites) actively served by Nginx.

Do you wonder why we need two directories to store our virtual host files? The answer is that in this way, we can create many virtual host files on our Nginx server, but we can enable them per our requirements.

For this guide, we will create virtual host files in our Nginx server to host multiple sites with multiple domains. The domain names are website1.com and website2.com.

1. Creating the Directory Structure

First, we must create a directory for each virtual host to store the different website content. We will place these directories in /var/www and name them after each domain name.

Run the following commands to create the directories:

sudo mkdir -p /var/www/website1.com
sudo mkdir -p /var/www/website2.comCode language: JavaScript (javascript)
Nginx Virtual Host Directory Structure

The -p flag in the command above tells mkdir to create any necessary parent directories.

2. Creating Test Pages for Each Website

Next, for demonstration purposes, let’s create an index.html file inside the domain’s document root directory so that we will have something to display.

sudo vim /var/www/website1.com/index.htmlCode language: JavaScript (javascript)

Paste the following lines:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Welcome to Website 1!</title>
    </head>
    <body>
        <h1>Welcome to Website 1!</h1>
    </body>
</html>Code language: HTML, XML (xml)

Now repeat the above step for website2.com.

sudo vim /var/www/website2.com/index.htmlCode language: JavaScript (javascript)

Paste the following lines:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Welcome to Website 2!</title>
    </head>
    <body>
        <h1>Welcome to Website 2!</h1>
    </body>
</html>Code language: HTML, XML (xml)

3. Create Nginx Virtual Host (Server Blocks)

To create an Nginx virtual host file inside the sites-available directory, execute the following command:

sudo vim /etc/nginx/sites-available/website1.com

It is worth noting that the Nginx virtual host configuration file can be named whatever you like, but it is generally a good idea to use the domain name.

Now, paste the following content into your virtual host file:

server {
    listen 80;
    server_name website1.com www.website1.com;
    root /var/www/website1.com;

    access_log /var/log/nginx/website1-access.log;
    error_log /var/log/nginx/website1-error.log;
}Code language: JavaScript (javascript)

To make things more transparent, let’s break down this syntax. First, here is what each parameter means:

  • listen: Specify on which port the Nginx server to listen for connections.
  • server_name: Here, we match requests for our domain. The directive holds a list of domain names we want to use to access our site.
  • root: The location of the directory in which we have stored our website files.
  • error_log: Full path to the log file in which we store this virtual host’s error logs.
  • access_log: Full path to the log file in which we store this virtual host’s access logs.

Now we can use our initial virtual host configuration as a basis for our second file. Just copy it over to create a new file:

sudo cp /etc/nginx/sites-available/website1.com /etc/nginx/sites-available/website2.com

Open the new file and adjust it to match our second (website2.com) domain name:

sudo vim /etc/nginx/sites-available/website2.com
server {
    listen 80;
    server_name website2.com www.website2.com;
    root /var/www/website2.com;

    access_log /var/log/nginx/website2-access.log;
    error_log /var/log/nginx/website2-error.log;
}Code language: JavaScript (javascript)

4. Enable Nginx Virtual Hosts (Server Blocks)

The last thing we need to do before testing enables the virtual hosts. We can do this by creating a symbolic link from the file to the sites-enabled directory:

sudo ln -s /etc/nginx/sites-available/website1.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/website2.com /etc/nginx/sites-enabled/

As you can see from the image below, these files are now linked to the sites-enabled directory.

Linked Nginx Configuration Files Into sites-enabled Directory

Before we go forward, let’s double-check that there aren’t any typos. Test the Nginx configuration for correct syntax:

sudo nginx -t

Finally, if no issues were found, restart the Nginx service to apply the changes:

sudo systemctl restart nginx

5. Testing the Virtual Hosts (Optional)

To test the Nginx virtual hosts, we first need to point our domain name records at the server’s IP address. In our case, the server IP address is 192.168.122.101.

If you are on Linux, open the /etc/hosts file on your desktop PC (the one from which you will perform the test) using the below command:

sudo vim /etc/hosts

And add the virtual domain names one by one, as shown below.

/etc/hosts

Save and close the file when you are finished. This way will allow us to test domains that we don’t own.

Now open your browser and enter www.website1.com and www.website2.com one by one. You will see the index pages of both domains, respectively.

Nginx Virtual Hosts Test

You have successfully configured two independent domains with Nginx.

6. Disable Nginx Virtual Hosts (Server Blocks)

To disable a virtual host in Nginx, we must remove the symlink we had created while enabling the virtual host file. For example, to disable website2.com, we have to execute the following command:

sudo rm -rf /etc/nginx/sites-enabled/website2.com

To apply the changes, we have to restart the Nginx server:

sudo systemctl restart nginx

Conclusion

This article shows you how to create Nginx virtual hosts (server blocks) and host multiple domains on a single Linux server. To create a virtual host for another domain, repeat the same steps. But, of course, Nginx can do a lot more.

Related: How to Configure Nginx to Work with PHP via PHP-FPM

In addition, if you want to know how to secure your website with a free SSL certificate, I recommend going through our guide, “How to Use Certbot to Get a Free Let’s Encrypt SSL Certificate.”

You can refer to the official Nginx documentation for more information on setting up an Nginx server.

Thanks for reading! I hope you found the article helpful and that you were able to set up the virtual hosts. Feel free to leave a comment if you have any questions.

Bobby Borisov

Bobby Borisov

Bobby, an editor-in-chief at Linuxiac, is a Linux professional with over 20 years of experience. With a strong focus on Linux and open-source software, he has worked as a Senior Linux System Administrator, Software Developer, and DevOps Engineer for small and large multinational companies.

Think You're an Ubuntu Expert? Let's Find Out!

Put your knowledge to the test in our lightning-fast Ubuntu quiz!
Ten questions to challenge yourself to see if you're a Linux legend or just a penguin in the making.

1 / 10

Ubuntu is an ancient African word that means:

2 / 10

Who is the Ubuntu's founder?

3 / 10

What year was the first official Ubuntu release?

4 / 10

What does the Ubuntu logo symbolize?

5 / 10

What package format does Ubuntu use for installing software?

6 / 10

When are Ubuntu's LTS versions released?

7 / 10

What is Unity?

8 / 10

What are Ubuntu versions named after?

9 / 10

What's Ubuntu Core?

10 / 10

Which Ubuntu version is Snap introduced?

The average score is 68%