Understanding NGINX Core Contexts
Tags: nginx, tutorial, webdev, server
Published: 2021-05-31 03:42:33


## What is NGINX ?
**Nginx** [engine x] is a free and opensource high performance **web-server** that can be used as reverse proxy, load balancer, SMTP proxy and a generic TCP/UDP proxy server. Nginx originally developed by **Igor Sysoev** in 2002 to solve C10k problem.


-------------------------------------------------------------


## NGINX Configuration file 
NGINX can be configured with `nginx.conf` file, By default this file is named as `nginx.conf` and placed under `/usr/local/nginx/conf`, `/etc/nginx`, or `/usr/local/etc/nginx`.


-------------------------------------------------------------



## What are  Directives and Contexts?
NGINX con­fig­u­ra­tion con­sists of key-value pairs called direc­tives. Direc­tives decides which configuration to apply.They can be organized and grouped into Blocks known as Contexts. Contexts are tree like structures that can be nested within one another and Direc­tives can  only been used within Contexts.




Directives looks like:

```conf
user nginx;
worker_processes 5;
```



Contexts look like:

```conf
# Global Context
....
....

# http Context 
http {
      ....
      ....
      # server Context
      server {
             ....
             ....
      }

}
```


-------------------------------------------------------------


## Global context
The "global" context is placed at the beginning of the core NGINX configuration file and is used to set the configuration for NGINX globally.

The global context allows module writer  to configure user, no.of works, file  to save the main process's PID, worker CPU affinity and niceness of worker processes. 


```conf
#global context

# global directive
user nobody;
worker_processes 1;
....
....

```

-------------------------------------------------------------


## Events context
The "events" context is contained within "global" context and  can be used to set global options for NGINX connection processing.There can only be a single events context defined within the NGINX configuration. 


```conf
#global context

# global directive
user nobody;
worker_processes 1;
....
....

#events context
events {
       # events directive
       ....
       ....
}
```

-------------------------------------------------------------


## HTTP context
The "http" context holds directives for handling HTTP and HTTPS traffic. The  Server context can be placed inside the HTTP context.


```conf
#global context

# global directive
user nobody;
worker_processes 1;
....
....

#events context
events {
       # events directive
       ....
       ....
}
# http context
http {
      # http directive
      ....
      ....
}
```


-------------------------------------------------------------


## Server context
The “server” context is declared within the "http" context. There can be multiple instance of server context within http context. Each server context instance is a virtual server to handle client request.

The **listen** and **server_name** directives within the server context will be used to determine which server context can be used to respond the request. The directives in this context can override the directives that may defined in the http context.


```conf
# http context
http {
      # server context
      server {
             # server directive
             listen: 80;
             server_name: example.com, www.example.com
             ....
             ....
      }      
      ....
}
```
-------------------------------------------------------------


## Location Context
The "location" contexts are used to define directives to handle client request. When a request for resource arrives at NGINX, it will try to match the URI to one of the locations and handle it accordingly. A location context can be  nested within server context and also within another location context.

```conf
# http context
http {
      # server context
      server {
             listen : 80;
             # first location context
             location parameter {
                      ....
                      ....
             }
             # second location context
             location parameter {
                      # nested location context
                      location parameter {
                               ....
                               ....
                      }
                  ....
             }
      }      
      ....
}
```

There are two types of parameter to the location directive: prefix strings (path names) and regular expressions. For a request URI to match a prefix string, it must start with the prefix string.A regular expression is preceded with the tilde (~) for case-sensitive matching, or the tilde-asterisk (~*) for case-insensitive matching.



```conf
# location with string (path parameter)
location /home/user/ {
         # URI starting with /home/user/ will match 
         # but /some/home/user/ won't 
         ....
}

# location with regular expression as parameter
location ~ /.html? {
         # URI that  has .html or .htm string
         # in it will match
         ....
}
```

-------------------------------------------------------------


## Upstream context
The "upstream" context is used to define and configure “upstream” servers. Basically, this context defines a named pool of servers that Nginx can then proxy requests to. This context will likely be used when you are configuring proxies of various types.  The upstream context should be defined within http context and outside the server context, to be used.

Once the upstream servers have been defined, the name of the same is available within the server context to pass the request to the pool of back-end servers.


```conf
http {
    # upstream context
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
    }
    # server context
    server {
           location / {
                    proxy_pass http://backend;
           }
    }

}
```
Here the upstream group has been named as backend, which consists of two server configurations.To pass requests to a server group, the name of the group(backend) has been specified in the proxy_pass.


-------------------------------------------------------------


## Mail context
NGINX can also be used a mail proxy. The "mail" context provides the ability to implement mail proxy.The mail context is defined in global context and outside of http context. 


```conf
# global  context
....
....
# mail context
mail {
     # mail directive
     ....
     ....
}
```

-------------------------------------------------------------


## If context
The "if" context provides conditional execution just like if in other programming languages. The if context is provided by the rewrite module and is the primary use of the if context. Since NGINX will test conditions of a request with many other valid directives, the if context should not be used for most forms of conditional execution thus might result in unexpected execution.


```conf
http  {
    server {
           # server context
           ....
           ....
           location location_match {
                    # location context
                    if (test_condition) {
                       # if context
                       ....
                    }
           }
    }
}

```

-------------------------------------------------------------


## Limit_except Context
The "limit_except" context is used to restrict the use of certain HTTP methods within a location context. 


```conf
....
# location context
location /restricted-write {
         # location context
         limit_except GET HEAD {
                      # limit_except context
                      deny all;
         }
}
```

Here client requests with GET and HEAD methods from any client will be allowed, but client requests with other methods are denied.  

-------------------------------------------------------------


## Some Best Practices
1.Declare directives in the highest context to which they are applicable, and overriding them in lower contexts to avoid code replication.
2.Use Multiple Sibling Contexts Instead of If Logic for Processing.


-------------------------------------------------------------


## Summary 
Now, you have a basic knowledge of nginx.conf file , its structure and core context to create your own conf file. Read [NGINX's documentaion](http://nginx.org/en/docs/dirindex.html) for more information about NGINX  context.