Understanding the Nginx Server Block

We can think of Server Blocks as specifications for individual web sites. Server blocks are the NGINX equivalent of Apache’s virtual hosts. So in order to host our websites on Nginx server, we need to understand the directives and settings that make up the server block.

Here is a sample server block configuration :

server {
  listen       80;
  server_name  _;

  location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
  }

  error_page  404              /404.html;
  location = /404.html {
    root   /usr/share/nginx/html;
  }
}

We can see different types of directives such as listen, root, server_name, location etc. Let’s explore those directives.

listen

It specifies the IP address / port combination that this server block is designed to respond to.

We can specify only the port or only the address or Both. If a port is omitted, the standard port(80) is used. And if an address is omitted, the server listens on all addresses. We can also use more than one listen directive, if needed. Here are some examples.

e.g., port is omitted :

listen     127.0.0.1; 
// will only respond to 127.0.0.1:80

e.g., address is omitted :

listen     50; 
// will respond to port 50 of all addresses. i.e: 127.0.0.1:50, localhost:50 etc..

e.g., IP address / port combination :

listen     192.168.25.19:60; 
// will only respond to 192.168.25.19:60

server_name

Nginx also checks the Host header of each request. When client makes a requests, Nginx checks if there is any server block that has a server_name directive defined with that “Host”. If there is a match, then that server block will responds to that request.

It will be easy to understand with an example.

Let’s create two new host in the /etc/hosts file :

127.0.0.1   localhost
127.0.0.1   www.site-one.com
127.0.0.1   www.site-two.com

So, now both site-one and site-two points to same IP address. But we want to put one website in site-one.com and another website in site-two.com. Let’s create two different server blocks for those two hosts :

# First Website
server {
  listen       70;
  server_name  www.site-one.com;
  
  root   /usr/share/nginx/html/site-one/;
}

# Second Website
server {
  listen       70;
  server_name  www.site-two.com;

  root   /usr/share/nginx/html/site-two/;
}

So now we can access the First Website with the address www.site-one.com:70, and the Second Website with www.site-one.com:70. Now, there is a Quiz. What website will open when we go to 127.0.0.1:70?

root

This directive specifies the directory where the website’s contents are located. As in our last example, the root directory was /usr/share/nginx/site-two for the Second Website. So when user hits the URL http://www.site-two.com:70/mypage.html, Nginx will load mypage.html file from that directory.

location

location block is used to decide how to process the request URI (after the domain name or IP address/port). e.g. :

location / {
  # configuration for processing all URIs that do not match other location blocks.
} 

location /one {
  # configuration for processing URIs with '/one'
}

location /two {
  # configuration for processing URIs with '/two'
}

A location can be defined either by a prefix string or by a regular expression. The syntax is :

location [modifier] match {
...
}

When there is no modifier, the match acts just as a prefix string for the incoming URL. e.g. :

location /two {
  # configuration for processing URIs with '/two'
}

And when any modifier exists, the way that Nginx matches the location will change.

Here is what different modifiers do :

How nginx performs the matching can be found on their offcial doc. Here is an example for illustrate different types of modifiers :

location = / {
    # Only matches the / query.
}

location / {
    # URI beginning with '/'
    # But the process continues searching
}

location /documents/ {
    # URI beginning with /documents/ 
    # But the process continues searching.
}

location ^~ /images/ {
    # URI beginning with /images/
    # The process stops searching
}

location ~* \.(gif|jpg|jpeg)$ {
    # Matches requests ending in gif, jpg or jpeg. 
    # URI beginning with /images/ are NOT handled here
}

A more detailed overview of how nginx porcesses a request can be found here

Comments

comments powered by Disqus