• Nginx HTTP Module and Configuration

    Nginx’s HTTP module comes with its own set of directives and structure blocks.

    Structure Blocks

    http

    The http block acts as the overarching block for all directives and sub-blocks.

    server

    A server block defines a website, as identified by a hostname (or many), or in Nginx parlance, a virtual host. server blocks cannot be placed outside of a http block.

    location

    A location block allows you to define settings for specific locations in a website. location blocks can be placed in a server block or nested within another location block.

    A location block is specified with a pattern that will be matched against the requested URI. This pattern can be quite complex, involving location modifiers.

    = modifier

    This modifier means the URI must match the pattern exactly. Only simple strings can be specified (no regular expressions).

    No modifier

    This modifier means the URI must begin with the pattern. Only simple strings can be specified (no regular expressions).

    ~ modifier

    This modifier means the URI must match the pattern, and is case sensitive. Regular expressions are allowed.

    ~* modifier

    This modifier means the URI must match the pattern, and is case insensitive. Regular expressions are allowed.

    ^~ modifier

    This modifier behaves the same as no modifier, except that Nginx will stop searching for other patterns if it has matched a location block with this modifier (see below for search order and priority).

    @ modifier

    This modifier is used to define a named location block, which can only be accessed internally by try_files or error_page (see below).

    As an example, given a pattern of /abcd or ^/abcd$:

    • http://website.com/abcd will match all modifiers
    • http://website.com/ABCD will match ~* modifier, as well as = and no modifier if your OS is case-insensitive
    • http://website.com/abcd?param1=param2 will match all modifiers (query strings are ignored)
    • http://website.com/abcd/ will match only no modifier, due to the trailing slash
    • http://website.com/abcde will match only no modifier

    Search order and priority

    Different modifiers have different priorities when Nginx is searching for a location block that matches a particular URI.

    In order from most important to least important:

    1. Matching on the = modifier
    2. Matching exactly on no modifier
    3. Matching on the ^~ modifier
    4. Matching on the ~ and ~* modifiers
    5. Matching on no modifier

    Module Directives

    Socket and host configuration

    listen

    Context: server

    Sets the address and port for IP, or path for a UNIX-domain socket. If the address is left out, then a wildcard (*) is assumed. If the port is left out, port 80 is assumed (unless the master process is run without root privileges, in which case port 8000 will be assumed).

    Also accepts ssl and spdy parameters for SSL and SPDY (SPDY practically requires SSL) connections respectively:

    listen 443 ssl spdy;
    

    More information on configuring Nginx for HTTPS.

    server_name

    Context: server

    Sets the hostname for the server block. Nginx will match against all server blocks’ server_name directive, choosing the first block that matches. If none of them match, then Nginx will match against the listen directive’s address parameter (see above).

    Allows wildcards and regex. Allows multiple hostnames.

    tcp_nodelay

    Context: http, server, location
    Default: on

    Enables or disables the TCP_NODELAY socket option for keep-alive connections. TCP implements a mechanism, using an algorithm called Nagle’s algorithm, that delays sending data over the packet by some empirically determined time (Linux sets it at 200ms) to reduce the number of overly-small packets being sent out and causing network congestion. In other words, it temporally buffers the data being sent. However, this feature is somewhat irrelevant nowadays, with much more bandwidth available on the interwebs. Recommended to keep on (disable Nagle’s algorithm).

    tcp_nopush

    Context: http, server, location
    Default: off

    The tcp_nopush option corresponds to the TCP_CORK option in the Linux TCP stack. TCP_CORK, like TCP_NODELAY, buffers data by blocking packets from being sent through the socket until the amount of data in the window reaches the Maximum Segment Size (MSS)1. Disabling tcp_nopush will allow partial frames to be sent. This option is only affected when the sendfile directive is enabled.

    sendfile

    Context: http, server, location
    Default: off

    One of the reasons why Nginx is famous for its speed in serving static files is due to the sendfile option, which uses the OS’s sendfile(2) function. The Linux’s man page explains it best:

    sendfile() copies data between one file descriptor and another. Because this copying is done within the kernel, sendfile() is more efficient than the combination of read(2) and write(2), which would require transferring data to and from user space.

    The sendfile() function itself takes 4 arguments, the first two of which are the file descriptors for reading (in_fd) and writing (out_fd). However, the man page specifies that:

    The in_fd argument must correspond to a file which supports mmap(2)-like operations (i.e., it cannot be a socket).

    Thus, sendfile() cannot be used for Unix sockets. That means sendfile() doesn’t work in conjunction with Unicorn for serving Rails applications. Still, you can and should enable sendfile for serving static files.

    tcp_nodelay, tcp_nopush and sendfile can work in conjunction. tcp_nopush ensures that only full packets are sent out, reducing network (header) overhead. When the last packet is sent, tcp_nopush is disabled by Nginx, and tcp_nodelay allows the the packet to be sent immediately, instead of waiting 200ms.

    reset_timedout_connection

    Context: http, server, location
    Default: off

    Turning this on will free up the memory assigned to the socket if the socket connection times out. Recommended to turn on.

    Paths and Documents

    root

    Context: http, server, location, if

    The location of the document root containing the files to be served.

    alias

    Context: location

    Aliases a specified location to another location, for example:

    server {
      server_name localhost;
      location /test/ {
        alias /test2/
      }  
    }
    

    Requests to http://localhost/test/ will be served from http://localhost/test2/

    error_page

    Context: http, server, location, if

    Allows you to specify error pages for 4-500 errors:

    error_page 404 /404.html
    error_page 500 /server_error.html
    

    index

    Context: http, server, location

    Defines the default page to serve if no filename is specified in the request. If autoindex is enabled, then Nginx will attempt to index the files automatically.

    try_files

    Context: server, location

    A directive that specifies the files to attempt to serve within a server or location block. A contrived example demonstrates how try_files works:

    location / {
      try_files $uri $uri.html $uri.php $uri.xml @proxy;
    }
    
    # the following is a "named location block"
    
    location @proxy {
      proxy_pass 127.0.0.1:8080;
    }
    

    try_files $uri is the “normal” behavior, where Nginx tries to locate the document with the exact specified URI. If it does not correspond to any existing file, Nginx will try to append .html to the URI and try, then with .php, then .xml, in that order. If all of these fail, then it defers the request to another location block. Another location block, if specified, must be the last argument.

    Client requests

    keepalive_requests

    Context: http, server, location
    Default: 100

    Defines the maximum number of requests that Nginx allows per keep-alive connection.

    keepalive_timeout

    Context: http, server, location
    Default: 75

    Defines the maximum number of seconds Nginx will wait for before closing a keep-alive connection. It also accepts an optional second argument that Nginx will use to add a Keep-Alive: timeout= HTTP header:

    keepalive_timeout 45 30;
    

    send_timeout

    Context: http, server, location
    Default: 60

    Defines the maximum number of seconds Nginx will wait between two write operations to the client before closing the inactive connection.

    client_body_timeout

    Context: http, server, location
    Default: 60

    Defines the maximum number of seconds Nginx will wait between two read operations from the client before responding with a 408 Request Timeout error.

    client_max_body_size

    Context: http, server, location
    Default: 1m

    Defines the maximum size of a client request body. Needs to be set appropriately if user file uploads are expected.

    MIME types

    Before serving a file, Nginx will inspect its file extension to determine what value to set in the response’s Content-Type header. Nginx already includes a basic set of MIME types in its default configuration file: include mime.types;. To handle file extensions not covered in mime.types, one can include a types block:

    types {
      image/jpeg jpg;
      application/json json;
    }
    

    Limits and restrictions

    limit_rate

    Context: http, server, location, if
    Default: No limit

    Limits the transfer rate of client connections.

    limit_rate_after

    Context: http, server, location, if
    Default: None

    Sets the amount of data to allow transferring before the limit_rate directive takes effect.

    internal

    Prevents external requests from accessing the specific location block:

    location /admin/ {
      internal;
    }
    

    File processing and caching

    open_file_cache

    Context: http, server, location
    Default: Off

    Enables Nginx caching for file descriptors. It accepts two arguments: max=X, where X refers to the maximum number of entries that can be cached, and inactive=Y, where Y refers to the number of seconds a cache entry should be stored. Y defaults to 60 seonds, meaning that cache entries will be cleared after 60 seconds, unless the open_file_cache_min_uses directive is specified (see below).

    open_file_cache_errors

    Context: http, server, location
    Default: Off

    Enables Nginx caching for errors related to file lookups, such as incorrect file permissions or non-existence of files. This is so that Nginx doesn’t have to repeatedly attempt accessing files it cannot serve.

    open_file_cache_min_uses

    Context: http, server, location
    Default: 1

    This directive allows you to tell Nginx not to remove file descriptors from the cache if its accessed more than a certain number of times, as defined by this directive:

    open_file_cache_min_uses 2;
    

    open_file_cache_valid

    Context: http, server, location
    Default: 60

    Defines the number of seconds Nginx will wait for before revalidating a cached entry.

    Other directives

    server_tokens

    Context: http, server, location
    Default: On

    Tells Nginx whether to include its version number in the response.

    underscores_in_headers

    Context: http, server
    Default: Off

    Allow or disallow underscores in custom HTTP header names (such as X_AUTH_TOKEN).

    Footnotes
    1. MSS is usually 40 or 60 bytes smaller than the Maximum Transmission Unit (MTU), since it doesn’t account for the TCP header or IP header.

  • Core Nginx Configuration and HTTP Load Testing with Autobench

    The Core module controls essential Nginx features, some of which will have a direct impact on performance, such as the number of worker processes. It also includes some directives that are useful for debugging.

    Official Nginx docs on the Core module

    Below, I cover the directives that I think have the greatest impact on performance or are critical to change from default values for security purposes.

    Core directives

    error_log

    Syntax: error_log file_path log_level
    Accepted values for log_level: debug, info, notice, warn, error, and crit
    Default: logs/error.log error

    This directive can be placed in main, http, server, and location blocks to indicate specific rules for logging.


    include

    Nginx file importing. See Nginx Configuration Syntax.


    pid

    Syntax: pid pid/nginx.pid
    Default: Defined at compile time

    Defines the path of the pid file.


    multi_accept

    Syntax: multi_accept on
    Default: off

    Defines whether worker processes will accept all new connections (on), or one new connection at a time (off).


    use

    Syntax: use epoll
    Default: Nginx will automatically choose the fastest one

    Specifies the connection processing method to use. The available methods are select, poll, kqueue, epoll, rtsig, /dev/poll, and eventport.

    For Linux systems, epoll seems to yield the best performance. Here is an interesting post comparing epoll and kqueue.


    user

    Syntax: user username groupname

    Defines the user that will be used to start the worker processes. It’s dangerous to set the user and group of worker processes to root. Instead, create a new user specifically for Nginx worker processes (www-data is canonical).

    user root root;
    # change to
    user www-data www-data;
    

    worker_connections

    Syntax: worker_connections 1024
    Default: 1024

    This sets the number of connections that can be received by each worker process. If you have 4 worker processes that can accept 1024 connections each, your system can accept a total of 4096 simultaneous connections. Related to worker_rlimit_nofile below.


    worker_cpu_affinity

    Syntax: worker_cpu_affinity 1000 0100 0010 0001

    Allows you to assign worker processes to CPU cores. For example, if you’re running 3 worker processes on a dual-core CPU (which you shouldn’t, see below), you can configure the directive to assign 2 worker processes to the first CPU core and 1 to the second CPU core:

    worker_cpu_affinity 10 01 10
    

    There are 3 blocks for 3 worker processes, and each block has 2 digits for 2 CPU cores.


    worker_priority

    Syntax: worker_priority 5
    Default: 0

    Adjusts the priority level of worker processes. Decrease this number if your system is running other processes simultaneously and you want to micromanage their priority levels.1


    worker_processes

    Syntax: worker_processes 1
    Default: 1

    This number should match the number of physical CPU cores on your system.

    worker_proceses 1;
    # set to match number of CPU cores
    worker_processes 4; # assuming a quad-core system
    

    worker_rlimit_nofile

    Syntax: worker_rlimit_nofile 200000
    Default: None, system determined

    worker_rlimit_nofile sets the limit on the number of file descriptors that Nginx can open. You can see the OS limit by using the ulimit command.

    Check out this excellent post for more on worker_rlimit_nofile. An excerpt:

    When any program opens a file, the operating system (OS) returns a file descriptor (FD) that corresponds to that file. The program will refer to that FD in order to process the file. The limit for the maximum FDs on the server is usually set by the OS. To determine what the FD limits are on your server use the commands ulimit -Hn and ulimit -Sn which will give you the per user hard and soft file limits.

    If you don’t set the worker_rlimit_nofile directive, then the settings of your OS will determine how many FDs can be used by NGINX (sic).

    If the worker_rlimit_nofile directive is specified, then NGINX asks the OS to change the settings to the value specified in worker_rlimit_nofile.

    In some configurations I’ve seen, the value is set at 2 times worker_connections to account for the two files per connection. So if worker_connections is set to 512, then a value of 1024 for worker_rlimit_nofile is used.

    HTTP Load Testing with Autobench

    The basic idea behind testing would be to test multiple load scenarios against different Nginx configuration settings to identify the ideal configuration settings for your expected load.

    Autobench

    A Perl wrapper around httperf that automatically runs httperf at increasing loads until saturation is reached. It can also generate .tsv graph files that can be opened in Excel.

    Download it from here, make and make install.

    A test command looks like this:

    $ autobench --single_host --host1 192.168.1.10 --uri1 /index.html --quiet --low_rate 20 --high_rate 200 --rate_step 20 --num_call 10 --num_conn 5000 --timeout 5 --file results.tsv
    

    Some Autobench options:

    --host1: The website host name you wish to test
    --uri1: The path of the file that will be downloaded
    --quiet: Does not display httperf information on the screen
    --low_rate: Connections per second at the beginning of the test
    --high_rate: Connections per second at the end of the test
    --rate_step: The number of connections to increase the rate by after each test
    --num_call: How many requests should be sent per connection
    --num_conn: Total amount of connections
    --timeout: The number of seconds elapsed before a request is considered lost
    --file: Export results as specified (.tsv file)

    TODO: Find out more about Apache JMeter and locust.io

    Graceful Upgrading

    To upgrade Nginx gracefully, we need to:

    1. Replace the binary
    2. Replace the old pid file and run the new binary2
    $ ps aux | grep nginx | grep master
    root   19377  0.0  0.0  85868   152 ? Ss  Jul07  0:00 nginx: master process /usr/sbin/nginx
    $ kill –USR2 19377
    
    1. Kill all old worker processes
    $ kill -WINCH 19377
    
    1. Kill the old master process
    $ kill -QUIT 19377
    
    Footnotes
    1. Priority levels range from -20 (most important) to 19 (least important). 0 is the default priority level for processes. Do not adjust this number past -5 as that is the priority level for kernel processes.

    2. See this Stack Overflow answer for what USR2 and WINCH mean;

  • Nginx Configuration Syntax

    The third post in the Nginx series.

    Nginx configuration consists essentially of key-value pairs called directives, which can be organised and grouped in blocks.

    Directives

    A directive is a key-value(s) pair that looks something like this:

    worker_processes 5;
    error_log logs/error.log info;
    

    Directives may accept more than 1 value, like the error_log directive. Directives may also have type restrictions on values - the worker_processes directive only accepts a single integer as a value.

    Directives are terminated with semicolons.

    Each module may introduce its own directives and blocks (discussed below) that can be set.

    Importing

    Nginx configuration files can be imported with the include directive:

    include mime.types;
    

    The effect of this importing is that the contents of the file will be inserted at the exact location of the include directive.

    include directives are processed recursively.

    The include directive supports filename globbing:

    include sites/*.conf
    

    where * may match any number (>0) of consecutive characters. This will import all of the .conf files in the sites folder.

    If a file specified by an include directive cannot be found, Nginx’s configuration check will fail, unless the include directive path includes a wildcard:

    include non-existent.conf # will fail
    include non-existent*.conf # will pass
    

    Blocks

    Modules may introduce blocks, which are logical structures that group module-specific directives together. Many directives can only be used within their associated blocks. The root of the main configuration file is also known as the main block.

    Blocks may be nested. Below we define a http block as introduced by the Nginx HTTP module. The http block accepts multiple server blocks defining Nginx virtual hosts, and each server block itself accepts multiple location blocks which contain directives specific to certain locations of the website:

    http {
    
      server {
        listen 80;
        server_name wowdomain.com;
        access_log /var/log/nginx/wowdomain.com.log;
    
          location ^~ /admin {
            access_log off;
          }
      }
    
    }
    

    In nested blocks, directives are inherited by child blocks and can be overriden. In this example, logging will be disabled just for the /admin/ path of wowdomain.com.

    Units

    One may use units:

    client_max_body_size 2M;
    
    • k or K: Kilobytes
    • m or M: Megabytes
    • ms: Milliseconds
    • s: Seconds
    • m: Minutes
    • h: Hours
    • d: Days
    • w: Weeks
    • M: Months (30 days)
    • y: Years (365 days)

    Variables

    Variables in Nginx start with $. Some modules introduce variables can be used when setting directives.

    Some directives do not support variables:

    error_log logs/error-$nginx_version.log;
    

    will actually log to a file called error-$nginx_version.log.

    String values

    Strings may be inputted without quotes unless they include blank spaces, semicolons or curly braces, then they need to be escaped with backslashes or enclosed in single/double quotes.

    Variables in quoted strings are expanded normally unless the $ is escaped.

    Comments

    Comments is Ruby-like, with lines prepended by a #:

    # this is a comment
    
  • Managing Nginx Processes

    The second in a series of Nginx posts.

    Nginx runs two different types of processes: the master process and worker processes.

    Master Process

    This should be started as root, because this will allow Nginx to open sockets below 1024 (it needs to be able to listen on port 80 for HTTP and 443 for HTTPS).

    Worker Processes

    These are spawned by the master process, and the user and group will as specified

    The Nginx binary accepts command-line arguments, of which a full list can be obtained by:

    /usr/local/nginx/sbin $ ./nginx -h
    

    -V tells you about Nginx as well as the options it was built with:

    $ nginx -V
    nginx version: nginx/1.4.6 (Ubuntu)
    built by gcc 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
    TLS SNI support enabled
    configure arguments: --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf ... (redacted) ...
    

    Starting

    To start Nginx, simply run the binary without any switches:

    /usr/local/nginx/sbin $ ./nginx
    

    Stopping

    There are two ways to stop Nginx - immediately using the TERM signal, or gracefully using the QUIT signal:

    /usr/local/nginx/sbin $ ./nginx -s stop
    
    /usr/local/nginx/sbin $ ./nginx -s quit
    

    Reloading Configuration

    /usr/local/nginx/sbin $ ./nginx -s reload
    

    All of the above commands will verify the configuration file each time they are run, even when you’re trying to stop Nginx. When you’re unable to stop Nginx using ./nginx -s stop, you may use kill or killall:

    $ killall nginx
    

    Testing Your Configuration

    Optionally, you can specify a path with -c so that you can test another configuration file:

    $ ./nginx -t -c /home/siawyoung/test.conf
    

    Nginx as a system service

    Adding Nginx as a system service allows us to:

    1. Control it with standard commands
    2. Have it launch and quit at system startup and shutdown automatically

    To add Nginx as a system service, we simply need to include a script in /etc/init.d/ called nginx1. There’re many resources out there which covers Nginx init scripts.

    This one seems quite popular and well-documented. Install it into your etc/init.d and make the script executable:

    $ sudo wget https://raw.github.com/JasonGiedymin/nginx-init-ubuntu/master/nginx -O /etc/init.d/nginx
    $ sudo chmod +x /etc/init.d/nginx
    

    Then, we need to associate the script with the operation system’s default runlevel2 so that the system runs this script on startup:

    $ sudo update-rc.d -f nginx defaults
    

    At this point, you should be able to start, stop, restart, or poll for Nginx status (assuming you used the script above):

    $ service nginx start # or stop | restart | status
    
    Footnotes
    1. Don’t forget to make it executable! (chmod +x /etc/init.d/nginx)

    2. Linux-based operating systems have 7 runlevels which correspond to different system states (0 means the system is shut down, 3 means the system is in multiuser mode, etc). Each state is associated with a folder in /etc called rc*.d. Each folder contains symbolic links to scripts located in init.d. A daemon called init is responsible for running the scripts associated with each state . Thus, what update-rc.d -f nginx defaults does is it creates a symbolic link to the nginx script within the rc*.d that is associated with the OS’s default state upon startup (for Ubuntu its 3).

      $ ls /etc | grep rc.\.d
      rc0.d
      rc1.d
      rc2.d
      rc3.d
      rc4.d
      rc5.d
      rc6.d
      
      $ ls /etc/rc3.d | grep nginx
      S20nginx
      

  • Downloading and Installing Nginx

    The first in a series of Nginx posts. The information here is heavily inspired from my reading of Clément Nedelcu’s excellent book Nginx HTTP Server and can be considered as my own personal reference.

    There are five main steps involved in installing Nginx, as outlined below:

    1. Install dependencies
    2. Download
    3. Configure
    4. Compile
    5. Install

    Nginx should be compiled from source, because:

    1. It may not be available in the enabled repositories of your Linux distro,
    2. Even if it is, it’s often an outdated version, and
    3. certain options and flags can only be configured at compile time.

    1. Install dependencies

    Nginx dependencies vary, according to the modules you require. Core dependencies include:

    GNU Compiler Collection (GCC)

    Nginx is written in C, so we need a C compiler.

    It’s quite likely that you already have GCC installed on your system. Test if gcc is installed:

    $ gcc
    

    Success: gcc: no input files
    Failure: gcc: command not found

    To install it:

    $ apt-get install build-essential
    

    Perl Compatible Regular Expression (PCRE)

    The Rewrite and HTTP Core modules need PCRE for parsing their regular expressions. We need to install both the library and its source: pcre and pcre-devel:

    To install it:

    $ apt-get install libpcre3 libpcre3-dev
    

    zlib

    The zlib library contains compression algorithms and is required in Nginx for gzip compression. Like PCRE, we need both the library and its source.

    To install it:

    $ apt-get install zlib1g zlib1g-dev
    

    OpenSSL

    Nginx relies on OpenSSL to serve secure pages.

    To install it:

    $ apt-get install openssl libssl-dev
    

    2. Download

    Nginx has three main branches: stable, mainline and legacy. It’s generally fine to use the mainline branch.

    Download and extract Nginx onto a directory of your choice:

    $ wget http://nginx.org/download/nginx-1.9.2.tar.gz
    $ tar zxf nginx-1.9.2.tar.gz
    

    3. Configure

    The configuration process consists of appending switches to the ./configure command. Some of these options affect the project binaries and cannot be changed post-compilation.

    objs/autoconf.err contains configuration error logs.

    Below is a brief overview of the available configuration switches.

    Path Options

    Configuration that tells Nginx where to put things.

    --prefix=

    Default: /usr/local/nginx

    Specify an absolute path on which to install Nginx to. If a relative path is specified, it will be taken as relative to /usr/local/nginx.

    Paths can also be specified for the Nginx binary (--sbin-path=), the main configuration file (--conf-path=), the pid file1 (--pid-path=), the lock file2 (--lock-path=), fallback log files (--http-log-path=, --error-log-path=), as well as paths where Nginx should look for its dependencies.

    Since the default --prefix path does not include a version number, upgrading Nginx will override the existing directory. It is recommended to override --prefix to include a version number, like this: --prefix=/usr/local/nginx-1.9.2, then create a symbolic link /usr/local/nginx to point to the latest versioned Nginx folder.

    Make sure the path specified by --prefix= exists and is read/writable by the user running the configuration and compilation.

    Prerequisites Options

    Configuration that tells Nginx where to look for dependencies and how to build them. You will need to configure this if you install dependencies in non-standard locations.

    For example, to configure an alternative path for the C compiler: --with-cc=, or to specify options for building zlib: --with-zlib-opt=.

    Module Options

    Configuration that tells Nginx which modules to include and exclude. Nginx has a modular architecture, which allows you to pick which functionalities you need easily.

    Here, I split Nginx modules by whether they are enabled or disabled by default.

    Modules Enabled By Default

    To disable these modules, the switch is of the syntax --without-http_<MODULE_NAME>_module, for example --without-http_rewrite_module.

    • Access (access)
      • “The ngx_http_access_module module allows limiting access to certain client addresses.”
    • Basic Authentication (auth_basic)
      • “The ngx_http_auth_basic_module module allows limiting access to resources by validating the user name and password using the “HTTP Basic Authentication” protocol.”
    • Automatic Index (autoindex)
      • “The ngx_http_autoindex_module module processes requests ending with the slash character (‘/’) and produces a directory listing.”
    • Browser (browser)
      • “The ngx_http_browser_module module creates variables whose values depend on the value of the “User-Agent” request header field.”
    • Charset (charset)
      • “The ngx_http_charset_module module adds the specified charset to the “Content-Type” response header field.”
    • Empty Gif (empty_gif)
      • “The ngx_http_empty_gif_module module emits single-pixel transparent GIF.”
    • FastCGI, uWSGI, SCGI (fastcgi, uwsgi, scgi)
      • “The ngx_http_fastcgi_module module allows passing requests to a FastCGI server.”
      • “The ngx_http_uwsgi_module module allows passing requests to a uwsgi server.”
      • “The ngx_http_scgi_module module allows passing requests to an SCGI server.”
    • Geo (geo)
      • “The ngx_http_geo_module module creates variables with values depending on the client IP address.”
    • Gzip (gzip)
      • “The ngx_http_gzip_module module is a filter that compresses responses using the “gzip” method.”
    • Headers (headers)
      • “The ngx_http_headers_module module allows adding the “Expires” and “Cache-Control” header fields, and arbitrary fields, to a response header.”
    • Limit Connections (limit_conn)
      • “The ngx_http_limit_conn_module module is used to limit the number of connections per the defined key, in particular, the number of connections from a single IP address.”
    • Limit Requests (limit_req)
      • “The ngx_http_limit_req_module module (0.7.21) is used to limit the request processing rate per a defined key, in particular, the processing rate of requests coming from a single IP address.”
    • Log (log)
      • “The ngx_http_log_module module writes request logs in the specified format.”
    • Map (map)
      • “The ngx_http_map_module module creates variables whose values depend on values of other variables.”
    • Memcached (memcached)
      • “The ngx_http_memcached_module module is used to obtain responses from a memcached server.”
    • Proxy (proxy)
      • “The ngx_http_proxy_module module allows passing requests to another server.”
    • Referer (referer)
      • “The ngx_http_referer_module module is used to block access to a site for requests with invalid values in the “Referer” header field.”
    • Rewrite (rewrite)
      • “The ngx_http_rewrite_module module is used to change request URI using regular expressions, return redirects, and conditionally select configurations.”
    • Split Clients (split_clients)
      • “The ngx_http_split_clients_module module creates variables suitable for A/B testing, also known as split testing.”
    • Server Side Include (SSI) (ssi)
      • “The ngx_http_ssi_module module is a filter that processes SSI (Server Side Includes) commands in responses passing through it.”
    • Upstream (upstream)
      • “The ngx_http_upstream_module module is used to define groups of servers that can be referenced by the proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, and memcached_pass directives.”
    • User ID (userid)
      • “The ngx_http_userid_module module sets cookies suitable for client identification.”

    Modules Disabled By Default

    To enable these modules, the switch is of the syntax --with-http_<MODULE_NAME>_module, for example --with-http_xslt_module.

    • Addition (addition)
      • “The ngx_http_addition_module module is a filter that adds text before and after a response.”
    • Auth Request (auth_request)
      • “The ngx_http_auth_request_module module (1.5.4+) implements client authorization based on the result of a subrequest.”
    • WebDAV (dav)
      • “The ngx_http_dav_module module is intended for file management automation via the WebDAV protocol.”
    • FLV (flv)
      • “The ngx_http_flv_module module provides pseudo-streaming server-side support for Flash Video (FLV) files.”
    • GeoIP (geoip) (requires libgeoip library dependency)
      • “The ngx_http_geoip_module module (0.8.6+) creates variables with values depending on the client IP address, using the precompiled MaxMind databases.”
    • Gunzip (gunzip)
      • “The ngx_http_gunzip_module module is a filter that decompresses responses with “Content-Encoding: gzip” for clients that do not support “gzip” encoding method.”
    • Gzip Static (gzip_static)
      • “The ngx_http_gzip_static_module module allows sending precompressed files with the “.gz” filename extension instead of regular files.”
    • Image Filter (image_filter) (requires libgd library dependency)
      • “The ngx_http_image_filter_module module (0.7.54+) is a filter that transforms images in JPEG, GIF, and PNG formats.”
    • MP4 (mp4)
      • “The ngx_http_mp4_module module provides pseudo-streaming server-side support for MP4 files.”
    • Perl (perl)
      • “The ngx_http_perl_module module is used to implement location and variable handlers in Perl and insert Perl calls into SSI.”
    • Random Index (random_index)
      • “The ngx_http_random_index_module module processes requests ending with the slash character (‘/’) and picks a random file in a directory to serve as an index file.”
    • Real IP (realip)
      • “The ngx_http_realip_module module is used to change the client address to the one sent in the specified header field.”
    • Secure Link (secure_link)
      • +The ngx_http_secure_link_module module (0.7.18) is used to check authenticity of requested links, protect resources from unauthorized access, and limit link lifetime.
    • SPDY (SPDY)
      • “The ngx_http_spdy_module module provides experimental support for SPDY.”
    • SSL (ssl)
      • “The ngx_http_ssl_module module provides the necessary support for HTTPS.”
    • Stub Status (stub_status)
      • “The ngx_http_stub_status_module module provides access to basic status information.”
    • Substitution (sub)
      • “The ngx_http_sub_module module is a filter that modifies a response by replacing one specified string by another.”
    • XSLT (XSLT) (requires libxml2 and libxslt library dependencies)
      • “The ngx_http_xslt_module (0.7.8+) is a filter that transforms XML responses using one or more XSLT stylesheets.”

    There are also third-party modules can be added on. --add-module=path will compile the module located at path into the binary.

    Miscellaneous Options

    There are some options that don’t fall in the above categories, mostly concerning mail server proxy or event management behavior.

    The most notable options that fall under this category are --user= and --group=, which specifies the user and group for starting Nginx worker processes.

    Running a ./configure --with-http_ssl_module --with-http_gzip_static_module produces some output that looks like this:

    $ ./configure --with-http_ssl_module --with-http_gzip_static_module
    
    checking for OS
     + Linux 3.13.0-52-generic x86_64
    checking for C compiler ... found
     + using GNU C compiler
     + gcc version: 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
    checking for gcc -pipe switch ... found
    checking for gcc builtin atomic operations ... found
    checking for C99 variadic macros ... found
    
    ...(redacted)-...
    
    Configuration summary
      + using system PCRE library
      + using system OpenSSL library
      + md5: using OpenSSL library
      + sha1: using OpenSSL library
      + using system zlib library
    
      nginx path prefix: "/usr/local/nginx"
      nginx binary file: "/usr/local/nginx/sbin/nginx"
      nginx configuration prefix: "/usr/local/nginx/conf"
      nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
      nginx pid file: "/usr/local/nginx/logs/nginx.pid"
      nginx error log file: "/usr/local/nginx/logs/error.log"
      nginx http access log file: "/usr/local/nginx/logs/access.log"
      nginx http client request body temporary files: "client_body_temp"
      nginx http proxy temporary files: "proxy_temp"
      nginx http fastcgi temporary files: "fastcgi_temp"
      nginx http uwsgi temporary files: "uwsgi_temp"
      nginx http scgi temporary files: "scgi_temp"
    

    4. Compile

    Once the ./configure command is executed successfully, a makefile is generated in the same directory, which can be used to compile Nginx by running make:

    $ make
    

    Success: make[1]: leaving directory...

    Any errors that occur here may be due to incorrect folder permissions or missing/too-recent/too-old dependencies.

    5. Install

    $ make install
    

    The command will copy the compiled files as well as other resources to the installation directory specified by --prefix. This may require root privileges, depending on the folder permissions for /usr/local.

    This step rarely presents problems.

    Next, we will look at how to control the Nginx demon, oops I meant daemon.

    Footnotes
    1. The pid file is a text file that contains the process ID.

    2. The lock file allows other programs to check if Nginx is already running and prevent Nginx from being started more than once.