Understanding the Nginx Contexts
Main configuration file is organized in a tree-like structure, defined by sets of brackets (that look like {
and }
). Areas that these brackets define are called “contexts”. They contain configuration details that are separated according to their area of concern. These divisions provide an organizational structure along with some conditional logic to decide whether to apply the configurations within.
Because contexts can be layered within one another, Nginx provides a level of directive inheritance. As a general rule, if a directive is valid in multiple nested scopes, a declaration in a broader context will be passed on to any child contexts as default values. The children contexts can override these values at will.
Directives can only be used in the contexts that they were designed for. Nginx will error out on reading a configuration file with directives that are declared in the wrong context.
The Core Contexts
Nginx utilizes core contexts in order to create a hierarchical tree and separate the concerns of discrete configuration blocks. These are the contexts that comprise the major structure of an Nginx configuration.
The Main Context
The most general context is the “main” or “global” context. It is the only context that is not contained within the typical context blocks and it looks like this:
# The main context is here, outside any other contexts
. . .
context {
. . .
}
Nginx uses an event-based connection processing model, so the directives defined within this context determine how worker processes should handle connections. Mainly, directives found here are used to either select the connection processing technique to use, or to modify the way these methods are implemented.
Usually, the connection processing method is automatically selected based on the most efficient choice that the platform has available. For Linux systems, the epoll method is usually the best choice.
HTTP
When configuring Nginx as a web server or reverse proxy, the “http” context will hold the majority of the configuration. This context will contain all of the directives and other contexts necessary to define how the program will handle HTTP or HTTPS connections.
The http context is a sibling of the events context, so they should be listed side-by-side, rather than nested. They both are children of the main context:
# main context
events {
# events context
. . .
}
http {
# main context
. . .
}
Some directives that you are likely to encounter with are:
default locations for access and error logs:
access_log
error_log
configure asynchronous I/O for file operations:
aio
sendfile
directio
configure the server’s statuses when errors occur:
error_page
configure compression:
gzip
gzip_disable
fine-tune the TCP
keep alive settings:
keepalive_disable
keepalive_requests
keepalive_timeout
Rules that Nginx will follow to try to optimize packets and system calls:
sendfile
tcp_nodelay
tcp_nopush
Additional directives configure an application-level document root and index files:
root
index
Set up the various hash tables that are used to store different types of data for server_names, types, and variables:
*_has_bucker_size
*_hash_max_size
The Server Context
The server context is declared within the http context. This is the first example of nested, bracketed contexts. It is also the first context that allows multiple declarations.
The general format for server context may look something like this. Remember that these reside within the http context:
# main context
http: {
# http context
server {
# first server context
}
server {
# second server context
}
}
The reason for allowing multiple declarations of the server context is that each instance defines a specific virtual server to handle client requests. You can have as many server blocks as you need, each of which can handle a specific subset of connections.
Each client request will be handled according to the configuration defined in a single server context, so Nginx must decide which server context is most appropriate based on details of the request. The directives which decide if a server block will be used to answer a request are:
- listen: The ip address / port combination that this server block is designed to respond to. If a request is made by a client that matches these values, this block will potentially be selected to handle the connection.
- server_name: This directive is the other component used to select a server block for processing. If there are multiple server blocks with listen directives of the same specificity that can handle the request, Nginx will parse the “Host” header of the request and match it against this directive.
The directives in this context can override many of the directives that may be defined in the http context:
logging
- the document
root
compression
We can also:
- configure files to try to respond to requests (
try_files
) - issue redirects and rewrites (
return
andrewrite
) - set arbitrary variables (
set
)