nginx webserver is a lightening fast Webserver with multitasking capabilities that is not only better than Apache and other standard Web servers but is also a very light weight one. Let’s look at the configuration options and the directory structure of nginx in this post.

Nginx key points to know before we jump right in

nginx: Nginx is a web server which can also be used as a reverse proxy, load balancer, mail proxy and http cache. Nginx is primarily used as a Webserver and we will be targeting at the same in this page.
nginx configuration file: /etc/nginx/nginx.conf
Directives: directives are nothing but configuration options available that can be specified in nginx.conf
Blocks/Contexts: Directives are grouped together in the form of groups [ called as Blocks or Contexts ]. The http block, server block and location block are three significant blocks to note.
Please note, some directives appear individually outside of any Blocks/Contexts.

Individual directives – Individual directives that is not a part of any block

user, worker_processes, error_log, pid are the four significant directives in nginx.conf.

'user': specifies the user to run the webserver as. 
'worker_processes': total number of processess needed to handle the connections. More process can be specified for a webserver serving a lot of load.
'error_log': you can specify the location of log file and the log level for errors. 
'pid': you can specify a file in which the pid of main nginx process is written.

Below is the section of nginx.conf listing the individual directives.

user  nginx;
worker_processes  4;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

Http block

The directives of the http block is used to specify configuration that handle http request/response such as configuring timeouts for sessions, page redirects for errors etc. Any directive that is added to this block is inherited across the web server. If you’re running multiple websites, all of them would inherit the directives of the http block. However if these directives are added to the server blocks for individual websites, then those directives override the ones specified outside.

Below is the section of nginx.conf listing the http block and its directives. As said before, these directives defines how requests are handled. These directives are to be looked into when you want to tweak, customize and tune performance for your website or web application. You may look at the official nginx directives listing for a description of each directive. But the one to immediately note is the ‘include’ directive. The include directive points to a path that contain configuration files for each of the website you’re hosting. The configuration files are expected to be to be of .conf pattern for this directive to work (not necessarily but in our below case). These files contain the server block, that can further have directives to define the behaviour of the website for which the server block is written.

http {
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                         '"$http_user_agent" "$http_x_forwarded_for"';
        access_log  /var/log/nginx/access.log  main;
        sendfile            on;
        tcp_nopush          on;
        tcp_nodelay         on;
        keepalive_timeout   65;
        types_hash_max_size 2048;
        include             /etc/nginx/mime.types;
        default_type        application/octet-stream;
    
        include /etc/nginx/conf.d/*.conf;
	
    }

Server block

Lets assume there are two websites we are hosting with different names, namely site1.com and site2.com
We will have its corrosponding server blocks here.

/etc/nginx/conf.d/site1.com.conf
/etc/nginx/conf.d/site2.com.conf

cat /etc/nginx/conf.d/site1.com.conf

server {
    listen         80;
    listen         [::]:80;
    server_name    site1.com;
    root           /var/www/site1.com;
    index          index.html;
    try_files $uri /index.html;
}

cat /etc/nginx/conf.d/site1.com.conf

server {
    listen         80 default_server;
    listen         [::]:80 default_server;
    server_name    site2.com;
    root           /var/www/site2.com;
    index          index.html;
    try_files $uri /index.html;
}

By default, the default server is the first one — which is nginx’s standard default behaviour. It can also be set explicitly as to which server should be default, with the default_server a. We have default server as site2.com by specifying the default_server parameter in it’s server block.

'listen': Used to specify the port number to use for listening. 
The second 'listen': Does just the same in ipv6. 
'server_name': can be used to set the name of the virtual site.
'root' Used to set the path that contains the files for the website i.e the document root. 
'index': Sets the index file that opens up when the web site is accessed.  

Location block

‘location’ block is a child block of server block and is used define the path of page to serve based on the request received.
For example, lets assume you have a file in the below location that you’d like to serve, when the visitor accesses site1.com/reports.

/var/www/site2.com/data1/reports/report.html

You can use the location directive as in the below example.

server {
    listen         80 default_server;
    listen         [::]:80 default_server;
    server_name    site2.com;
    root           /var/www/site2.com;
    index          index.html;
    try_files $uri /index.html;
	
	    location /reports {
            index          report.html;
            try_files $uri /data;
                       }

      }

The ‘try_files’ directive will automatically search the document root of the server block and look for the ‘data’ directory and then it will look for ‘reports’ directory under it, and it will serve the report.html since that is specified as index.

Now the advantage here is speed. The webserver does not have to search through the entire tree since you provide the explicit path to the directory that contains the files that you want to serve.

Please note, you can have a ‘root’ directive for each location, however it is not a best practice since If you add a root to every location block then a location block that isn’t matched will have no root.

One of the other common directives is ‘error_page’, which is used to specify path to another page when the requested page is not found.

server {
    listen         80 default_server;
    listen         [::]:80 default_server;
    server_name    site2.com;
    root           /var/www/site2.com;
    index          index.html;
    try_files $uri /index.html;
    error_page 404 /404.html;	
	    
		location /reports {
            index          report.html;
            try_files $uri /data;
                          }
      
        location = /404.html {
                root /var/www/error/;
                internal;
                             }
		}

‘return’ directive can be used to return codes based on http requests.

  		
server {
    listen         80 default_server;
    listen         [::]:80 default_server;
    server_name    site2.com;
    root           /var/www/site2.com;
    index          index.html;
    try_files $uri /index.html;
	    
		location /not_found {
             return 404;
        #another way to handle 404
						    }
      
        location /report {
		#redirect to new url using 301 - URL moved status
             return 301 http://site2_new.com
                internal;
        
                         }
    	}
		

We have looked at the directory structure of nginx and the primary configuration directives needed to spin up an nginx webserver to host a website. We will look forward to discuss further options available in nginx, especially in the location context, such as using regex to decide a match for best page to serve for a request etc, in the later posts.