Looking to place your advertisement?

Advertise your brand and services to thousands of IT enthusiasts!

How to setup Nginx server blocks (virtual hosts)

  • avatar
  • 5 mins read

Nginx logically divides the configurations in order to serve different content into blocks. A server block is a subset of Nginx’s configuration that defines a virtual server used to handle requests of a defined type. Administrators often configure multiple server blocks and decide which block should handle which connection based on the requested domain name, port and IP address.

Note: "VirtualHost" is an Apache term. Nginx does not have virtual hosts, it has “server blocks” that use the server_name and listen directives to bind to TCP sockets.


Create a server block

By default, Nginx contains one server block called default which we can use as a template for our own configurations. Below you can see two server blocks for our example domain (domain.com).

First we will create a new configuration file to handle domain.com requests:

touch /etc/nginx/sites-available/domain.com

And fill it with the following content:

server {
# Listening port
listen 80;
listen [::]:80;

# SSL configuration
#listen 443 ssl http2;
#listen [::]:443 ssl http2;

#ssl_certificate /root/file.crt;
#ssl_certificate_key /root/file.key;

# Matching domain
server_name domain.com;

return 301 http://www.domain.com$request_uri;

This block will handle each request and redirect it to www.domain.com. Don't forget to replace the example domain with your own domain.

Then we will create another configuration file to handle www.domain.com requests:

touch /etc/nginx/sites-available/www.domain.com

And fill it with the following content:

server {
# Listening port
listen 80 default_server;
listen [::]:80 default_server;

# SSL configuration
#listen 443 ssl http2;
#listen [::]:443 ssl http2;

#ssl_certificate /root/file.crt;
#ssl_certificate_key /root/file.key;

# Location of our site content
root /var/www/html/public;

# Matching index files
index index.html index.htm index.php;

# Additional security headers
#add_header Strict-Transport-Security "max-age=3600";
#add_header X-Content-Type-Options "nosniff";
#add_header X-Frame-Options "sameorigin" always;
#add_header X-XSS-Protection "1; mode=block";

# Matching domain
server_name www.domain.com;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.php?$query_string;

# Pass PHP scripts to FastCGI server
location ~ .php$ {
include snippets/fastcgi-php.conf;

# With php-fpm (or other unix sockets):
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
# With php-cgi (or other tcp sockets):

# Cache media: images, icons, video, audio, HTC
location ~* .(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";

# Cache CSS, JS and fonts
location ~* .(?:css|js|woff2)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";

# Deny access to .well-known folder
location ~ /.(?!well-known).* {
deny all;

Note: for convenience we can put both blocks into one single configuration file.

First, we need to look at the listen directives. Only one of our server blocks on the server can have the default_server option enabled. This specifies which block should serve a request if the server_name requested does not match any of the available server blocks. Note that the secure (HTTPS) connections will not be handled as configuration lines for that are commented in both files.

Next, we need to specify the document root, specified by the root directive. Point it to the site’s index file location and specify the index file which will handle the request with the index directive (you should remove index.php if PHP-FPM is not installed).

The configuration file can also be used to add headers using the directive add_header.

Afterwards, we need to modify the correct server_name to match requests for our domain (in our example case: www.domain.com).

Finally, we define actions and caches based on the incoming request rules with location directive.

Enable server block

Now that we have our server blocks defined, we need to enable them. We can do this by creating symbolic links from these files to the sites-enabled directory, which Nginx reads from during startup:

sudo ln -s /etc/nginx/sites-available/domain.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/www.domain.com /etc/nginx/sites-enabled/

Test and apply the configuration

Make sure that there are no errors in any of your Nginx configuration files running the following command:

sudo nginx -t

If no problems were found, restart Nginx to apply your changes:

sudo systemctl restart nginx

Define additional server blocks

Since Nginx allows the administrator to define multiple server blocks that function as separate virtual web server instances, it needs a procedure for determining which of these server blocks will be used to satisfy a request.

It does this through a defined system of checks that are used to find the best possible match. The main server block directives that Nginx uses during this process are the listen directive and the server_name directive.

Basically, to create additional server blocks, we must follow all previous steps defining, enabling and applying the specific configuration for each site.

 Join Our Monthly Newsletter

Get the latest news and popular articles to your inbox every month


Leave a Reply

Your email address will not be published.

Replying to message:

Hey visitor! Register your account and get access to featured articles and more - it's free.