Skip to content

Nginx

Nginx ("engine-x") is described as an event-based reverse proxy server. This refers to the fact that it has an asynchronous architecture, unlike its competitors Apache and IIS which create a new blocking thread per connection. Nginx is much newer than Apache which started in 1995, although it has seen widespread adoption since 2008, growing mostly at Apache's expense. A typical and favored deployment is to place Nginx in the front-end and Apache in the back-end to combine the advantages of both platforms.

Nginx follows the convention of even version numbers being stable and odd numbers being mainline or development.

# /etc/yum.repos.d/nginx.repo

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
dnf install nginx

# /etc/apt/sources.list

deb http://nginx.org/packages/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/ubuntu/ trusty nginx
curl -fsSL http://nginx.org/keys/nginx_signing.key
apt-key add nginx_signing.key
apt install nginx

Depending on installation method and distribution, configurations can exist in various directories. A config can be explicitly specified at runtime with --conf-path/-c.

This option also appears in the output of ps for the Nginx master process, which is one way of interrogating which config is being used for the current Nginx instance. Nginx can also be interrogated for its default config with -t

Nginx config files contain directives:

  • Simple directives like listen *:80; contain a name, multiple optional parameters, and a closing semicolon. Parameters themselves can pass a value after an equal sign, i.e. backlog=511.
  • Context directives (or simply "contexts", also "block directives") like events, http, and server wrap a group of other directives in a pair of braces and can be nested. Most simple directives can only be declared in specific contexts.
  • There is also an implied main context which wraps all the contents of the file, and putting a simple directive into the main context means making it a top-level statemtn.
  • Comments can be written using #

Examples

A very simple representative config that creates an HTTP server listening on port 80 of every network interface, with no HTTP Host specified, from the specified root path:

Default
events {
}

http {
  server {
  }
}
Expanded with explicit values
user nobody nogroup;
worker_processes 1;

events {
  worker_connections 512;
}

http {
  server {
    listen *:80;
    server_name "";
    root /usr/share/nginx/html;
  }
}
http {
  server {
    listen 8080;
    root /www;

    location /images {
      root /;
    }
  }
}
events { }
nginx -s stop
nginx -s start
nginx restart

Reverse proxy

Each Nginx virtual server should be described by a file in the /etc/nginx/sites-available directory. These are linked to by symlinks placed in /etc/nginx/sites-enabled. Configuring a reverse proxy involves associating routes to proxied servers in these virtual server configs.

server {
  listen 80;
  location / {
    proxy_pass "http://127.0.0.1:8000";
  }
}

The configuration to serve static files placed in the local directory /path/to/staticfiles from the URL /static is:

location /static/ {
  root /path/to/staticfiles/
}

Load balancer

A load balancer is similar to a reverse proxy, with the following differences.

  • Load balancers perform reverse proxy across many backends, rather than a single one
  • Load balancers operate at either Layer 7 or Layer 4, whereas a reverse proxy operates only at Level 7
  • Load balancers are expected to handle much higher scale.

Load balancers themselves tend to be load balanced by DNS servers, which can serve multiple A records to clients which are supposed to choose one of the IP addresses at random. Some DNS providers like AWS Route 53 randomize the order of these records per query.

http {
  upstream backend {
    server 192.0.2.10;
    server 192.0.2.11;
  }

  server {
    listen 80;

    location / {
      proxy_pass http://backend;
    }
  }
}

📘 Glossary

default server block
First server block defined in the config
events
Context that governs connection processing configuration. Events can only be declared in the main context and there can only be a single events defined within the configuration.
http
Context that allows configuration of HTTP servers and typically serves as a container for the server context. Directives that are intended to apply to multiple server contexts are typically placed within the http context.
listen
Simple directive in the server context that configures the network interfaces and ports to listen on for requests.
server {
    listen *:80;
    listen *:81;
}
location

Context directive used when there is not a 1:1 mapping between path of the HTTP request and the filesystem. Prefix location blocks, the most basic implementation, allow various root directories to be specified depending on the request path.

Various modifiers can be used to modify how the request path is matched. When resolving paths, the most specific match is used.

Location blocks in order of precedence:

  • Exact match modifier (=)
  • Order matters with regex blocks because the first match will be used.
    • Non-regex prefix (^~) overrides any regex match
    • Case-sensitive regex (~)
    • Case-insensitive regex (~*)
  • Prefix (no modifier)
location /images/ {
    root /var/www/images;
}

location = /images/business_cat.gif {
    # ...
}

location ~ \.(gif|jpg)$ {
    # ...
}

location ~* \.(GIF|JPG)$ {
    # ...
}

location ^~ /foobar/images {
    root /var/www/foobar;
}
server (context directive)
http-context context directive.
server (simple directive)
upstream-context directive that specifies a backend node. Additional parameters can specify load-balancing behavior.
- **weight** controls weighting of backend nodes (default value is 1)
- **max_fails** controls the number of times that the server can be marked as unhealthy before it is removed from the pool
- **fail_timeout** controls the time a server is removed from the pool when it is marked unhealthy, and for how long `max_fails` is good for
server_name
Server context simple directive that enables virtual hosting. Values of this directive are matched to the HTTP GET request header's Host. If no matches are found, nginx uses the default server block.
upstream
http-context simple directive that can, using the server simple directive, specify a pool of backend server.
upstream backend {
    server 192.0.2.10:443 weight=3;
    server app1.example.com;
    server unix:/u/apps/my_app/current/tmp/unicorn.sock;
}
Each server directive can additionally
user
Main context simple directive that sets the Unix user and group that nginx worker processes will run as; by default nobody and the group is nogroup.
worker process
The non-root nginx process that serves incoming HTTP requests. Each worker process is single-threaded and runs a non-blocking event loop to process requests efficiently.
worker_connections
Main context simple directive that sets the maximum number of simultaneous connections that can be opened by each worker process.
worker_processes
Main context simple directive that sets the number of worker processes to serve HTTP requests (1 by default).