WittCode💻

Nginx - nginx.conf

By

Learn how to configure nginx with nginx.conf, the structure of nginx.conf, what nginx contexts are including an overview of the global, events, http, mail, and server contexts, what nginx directives are, and how to reload nginx with a new configuration.

Table of Contents 📖

Nginx Configuration

The main configuration file for nginx is called nginx.conf. The location of this file varies depending on how nginx was installed. For this series, it will be located inside /etc/nginx/nginx.conf. We can print the contents of this file by using cat /etc/nginx/nginx.conf.

cat /etc/nginx/nginx.conf

The output should be similar to the following.

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}


#mail {
#	# See sample authentication script at:
#	# http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
# 
#	# auth_http localhost/auth.php;
#	# pop3_capabilities "TOP" "USER";
#	# imap_capabilities "IMAP4rev1" "UIDPLUS";
# 
#	server {
#		listen     localhost:110;
#		protocol   pop3;
#		proxy      on;
#	}
# 
#	server {
#		listen     localhost:143;
#		protocol   imap;
#		proxy      on;
#	}
#}

Nginx Directives

Nginx configuration consists of contexts and directives. A directive is a key-value pair that determines the configurations to apply. For example, at the top of nginx.conf, we see the directive user www-data. Here, the key is user and the value is www-data. We can also see the directive worker_processes auto. Here, the key is worker_processes and the value is auto. These directives are grouped into blocks known as contexts.

Nginx Contexts

From looking at the contents of nginx.conf, it is clear that this file is organized in a hierarchical fashion using brackets. For example, at the bottom of the file we can see the word mail, some brackets, and then some declaratives.

mail {
    auth_http localhost/auth.php;
    pop3_capabilities "TOP" "USER";
    imap_capabilities "IMAP4rev1" "UIDPLUS";
}

Then, nested within mail, we can see the word server, some brackets, followed by more directives.

mail {
    auth_http localhost/auth.php;
    pop3_capabilities "TOP" "USER";
    imap_capabilities "IMAP4rev1" "UIDPLUS";

    server {
        listen     localhost:143;
        protocol   imap;
        proxy      on;
    }
}

Within nginx, these bracketed areas are called contexts. Currently in this file we can see four contexts present: events, http, mail, and server. Contexts contain configuration information for specific areas, allowing for nginx's configuration to be organized. Contexts can also be nested as seen with the two server contexts nested inside a mail context.

Nginx Global Context

We can also see the following directives outside of any context.

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

These directives are in what is known as the global context and they specify the core functionality of nginx. For example, in the configuration file we can see four directives: user www-data, worker_processes auto, pid /run/nginx.pid, and include /etc/nginx/modules-enabled/*.conf. User specifies the user to run the worker processes as, worker_processes specifies the number of worker processes, pid specifies the file to save the master process's PID, and include includes another file.

Nginx Events Context

Now lets talk about the events context. The events context is captured between the brackets following the word events.

events {
    # events context
}

There can only be one events context within an nginx configuration. The events context is used for connection processing (nginx processes connections in an event-based way). By default, we can see the directives worker_connections and multi_accept.

events {
    worker_connections 768;
    # multi_accept on;
}

The directive worker_connections is the number of simultaneous connections a worker process can work with. The multi_accept directive determines whether a worker process can accept one new connection at a time. The multi_accept directive is off by default meaning a worker process will accept one new connection at a time as opposed to all new connections at a time. It is recommended to keep the default value (off). These are just examples of directives that impact connection processing.

Nginx HTTP Context

The http context goes between curly braces following the word http.

http {
    # http context
}

The http context houses directives that handle HTTP/HTTPS traffic. This context will hold the majority of configuration when using nginx as a web server or reverse proxy. As we will see later, the server context is usually nested within the http context and provides more specific details on handling http requests. Directives only listed inside the http context are usually more global settings. For example, we can use the http contex to optimize serving content by working with packets.

##
# Basic Settings
##

sendfile on;
tcp_nopush on;
tcp_nodelay on;

Configuring the compression of data with gzip.

##
# Gzip Settings
##

gzip on;

# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

Setting the path for error and access logs.

##
# Logging Settings
##

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

And specifying SSL ssettings.

##
# SSL Settings
##

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;

Nginx Mail Context

The mail context uses the word mail followed by brackets.

mail {
    # mail context
}

The mail context is used to configure nginx to behave as a mail proxy server. For example, nginx can provide access to POP3 and IMAP mail servers, as seen by the nested server contexts.

mail {

    server {
        listen     localhost:110;
        protocol   pop3;
        proxy      on;
    }
    
    server {
        listen     localhost:143;
        protocol   imap;
        proxy      on;
    }

}

Nginx Server Context

The server context is nested within other contexts. It is the word server followed by brackets.

mail {

    server {

    }

}

We can declare multiple server contexts within a context.

mail {

    server {
        
    }

    server {

    }

}

The server context represents a server. More specificaly, it represents a server at a particular IP address and port that handles client requests. These servers can be configured to handle subsets of client connections. We will go more in depth into these contexts as the series progresses.

Changing nginx.conf

Now, lets edit nginx.conf and reload nginx with this new configuration. Remove the mail context from nginx.conf by using nano.

sudo nano nginx.conf

After removing the mail context, the contents of nginx.conf should be the following.

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Now lets reload nginx with this new configuration.

sudo systemctl reload nginx

If we run sudo systemctl status nginx, nginx should be running fine still.

sudo systemctl status nginx

Now, lets introduce an error and reload nginx. Remove a curly brace from the http context and try reloading nginx with sudo systemctl reload nginx.

sudo systemctl reload nginx

Output should be similar to the following.

Job for nginx.service failed.
See "systemctl status nginx.service" and "journalctl -xe" for details.

However, nginx should still be running but with a message displaying that there was an error with reloading. To check, run sudo systemctl status nginx.

sudo systemctl status nginx

Output should be similar to the following.

● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2022-06-28 14:22:56 CEST; 1 day 11h ago
    Docs: man:nginx(8)
Process: 51091 ExecReload=/usr/sbin/nginx -g daemon on; master_process on; -s reload (code=exited, status=1/FAILURE)
Main PID: 1108 (nginx)
    Tasks: 13 (limit: 18997)
Memory: 15.6M
CGroup: /system.slice/nginx.service
        ├─ 1108 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
        ├─51038 nginx: worker process
        ├─51039 nginx: worker process
        ├─51040 nginx: worker process
        ├─51041 nginx: worker process
        ├─51042 nginx: worker process
        ├─51043 nginx: worker process
        ├─51044 nginx: worker process
        ├─51045 nginx: worker process
        ├─51046 nginx: worker process
        ├─51047 nginx: worker process
        ├─51048 nginx: worker process
        └─51049 nginx: worker process

Jun 30 02:20:42 wittcode-Blade systemd[1]: Reloading A high performance web server and a reverse proxy server.
Jun 30 02:20:42 wittcode-Blade nginx[51091]: nginx: [emerg] directive "http" has no opening "{" in /etc/nginx/nginx.conf:17
Jun 30 02:20:42 wittcode-Blade systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Jun 30 02:20:42 wittcode-Blade systemd[1]: Reload failed for A high performance web server and a reverse proxy server.

We can see a message saying: "http" has no opening "{" in /etc/nginx/nginx.conf:17. Now, go back into nginx.conf, fix that error, and reload nginx again with sudo systemctl reload nginx.

sudo systemctl reload nginx

Now we have successfully changed the configuration of nginx.conf. To be fair, we just removed some commented out information on the mail context but this is a good start.

Nginx - nginx.conf