Skip to content

Nginx Virtual Hosts

Nginx virtual hosts give system administrators the ability to host multiple websites from a single server. The ability to host multiple websites on one server helps maximize the utility of said system; this keeps costs low and reduces the number of physical systems needed. HTTP has been specifically designed with this common use case in mind. Through the use of either IP addresses or HTTP’s headers, modern web servers can forward a user to the destination they intended to reach.

What is an Nginx Virtual Host?

“Virtual Hosts” are the logical separation of websites used by web servers. Via a properly build configuration, the software is instructed to check any incoming requests for information hinting at where the requesting user wished to go. This is accomplished through one of two methods. The first is through having multiple IP addresses assigned to the server. While this is an effective way to properly partition incoming traffic, this also gets expensive very quickly. IPv4 addresses are somewhat rare; adding cost to acquire additional ones.

The second method is through name-based hosts. These virtual hosts use headers within the HTTP requests to partition the requests. As the vast majority of websites have a domain name associated with them, this is generally the preferred method to make the separation.

How do Nginx Virtual Hosts Work?

In Nginx parlance, a “virtual host” is referred to as a “server block”. The functionality is essentially the same as other web server; the implementation is somewhat different.

What is IP Based Virtual Routing

Configuring Nginx to allow for request routing based on IP addresses is straightforward. The server blocks in the configuration files would contain a line similar to the following:

Code language: CSS (css)

Each block requires a listen value which does not overlap with any other server blocks. No server_name is specified.

What is Name Based Virtual Hosting

For name-based Nginx virtual hosts, the web browser connects to whatever IP address is specified in the A record for the domain. As the same address is specified in all server blocks, we are not able to differentiate requests in this manner. However, the Host field in the HTTP header makes up for this.

Unlike other protocols, HTTP includes a plaintext header which is sent with every request. This header contains information such as the useragent of your web browser and the domain of the website you are requesting. So, when you type into your web browser, the browser first retrieves the IP address of Wikipedia from its DNS server. It then sends an HTTP request to said server. Contained within is the following:

Code language: CSS (css)

This field is key to the functioality of name based Nginx virtual hosts.

Setting up Domains

To get started, we need to configure the domains used throughout the rest of the tutorial.

Running multiple websites in production requires purchasing the domains from an Internet registrar. The DNS server of your registrar has A records associating your domains with the IP of your server. This enables anyone with an Internet connection to connect.

However, testing doesn’t require publicly available domain names. Any sort of DNS record will work. As long as the web browser sets the Host field correctly, the virtual hosts will work as intended.

We’re going to modify the hosts file on our local computer to fake the domains.

On Linux and other Unix-like operating systems, this file can be found at /etc/hosts. Open this file in your favorite editor and add the following at the bottom of the file: server1.local subdomain.server1.local
Code language: CSS (css)

You must format these entries with tabs. They should match the other entries in the file. We have just instructed our computer to locally map these domain names to these IPs. If we now go into the terminal and run ping server1.local we should successfully receive a response from our loopback address.

Installing Nginx

With our domains properly configured, it is time to install Nginx. On Debian Linux and its derivatives, open up the terminal and run the following:

sudo apt install nginx

This command will install Nginx. Now, we need to start and enable the service before it will run.

sudo systemctl enable nginx sudo systemctl start nginx

We now have our web server installed and running. Open your web browser and go to You should see a greeting message from Nginx. At this point, Nginx blindly assumes that any HTTP requests hitting its IP address are part of one single virtual server. We now need to modify this.

Configuring Server Blocks in Nginx

Now that we have nginx configured, it is time to configure our virtual domains. At this point, if you were to go to any of our domains in your browser, you’d get the same message as for This is due to the fact that the web server is currently ignoring the Host field. Instead, it is always returning the one and only virtual server we have configured.

Modifying the Nginx Configuration

To set up a virtual host, open /etc/nginx/sites-enabled/server1.local.conf file. The HTTP blocks within the Nginx configuration contain the defined virtual hosts. These blocks need at a minimum a port to listen on, a domain to listen for, and a root directory to pull files from.

server { listen 80; root /usr/share/nginx/first_domain; server_name server1.local; }

Now, reload the Nginx server by running the following:

sudo systemctl reload nginx

A side note: reload and restart are not the same thing. In particular, reload simply instructs Nginx to reload its configuration files from disk. It will not stop running if any of the files have syntax errors. Instead, it will continue running with the configuration from before. In contrast, the restart command stops the server on incorrect config formatting, taking down any previously running websites until the issue is corrected.

This doesn’t make a huge difference for us now. However, on production servers this can be a huge problem. This is especially a problem if you are running a large number of websites all on the same instance. Having one site go down is bad. Having thirty sites all go down at once is catastrophic.

Creating the Root Directory for the Server Block

Now try accessing server1.local again. You should receive a 404 error. This is normal. We have not yet created any directories for it and therefore Nginx has no content to display.

Run the following commands:

sudo mkdir /usr/share/nginx/first_domain sudo vi /usr/share/nginx/first_domain/index.html

Enter the following content into the file:

<html> <head> <title>Test Website</title> </head> <body> This is a <strong>Test</strong> </body> </html>
Code language: HTML, XML (xml)

Nginx now has content to serve.

Reloading the page will now render our code. We now have our first functional virtual host. At this point it is only capable of serving static files from the root directory.

Hosting Multiple Websites Under One Domain With Subdomains

Now, let’s go ahead and configure a virtual host for the subdomain we defined earlier. Insert the following into /etc/nginx/sites-enabled/subdomain.local.conf.

server { listen 80; root /usr/share/nginx/subdomain; server_name subdomain.server1.local; }

Now, once again reload Nginx by running sudo systemctl reload nginx. If you now attempt to access this subdomain, you will receive the same 404 error. The virtual host needs a root directory specified before it will serve any files.

The server_name directive is very flexible. You can make one virtual server match to multiple different domains by using wildcards (*). For example:

server_name *
Code language: CSS (css)

This makes Nginx forward any requests to, or any other subdomain to this specific website.


To summarize, virtual hosts are an extremely powerful tool which allow you to host many different websites on one server. You are even able to host many different websites on one domain via the use of subdomains. These virtual hosts allow you to consolidate website hosting and therefore greatly help to reduce costs. They’re a vital tool for system administrators and are an essential part of any Nginx user’s toolkit.

Published inNginxSystem AdministrationWeb Hosting

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *