Nginx HTTP Server - Third Edition - Sample Chapter
Nginx HTTP Server - Third Edition - Sample Chapter
Third Edition
Nginx is a lightweight HTTP server designed for
high-traffic websites, with network scalability as the
primary objective. With the advent of high-speed Internet
access, short loading times and fast transfer rates have
become a necessity. This free, open source solution
will either come as a full replacement for other software
such as Apache, or stand in front of your existing
infrastructure to improve its overall speed.
$ 44.99 US
28.99 UK
P U B L I S H I N G
Clment Nedelcu
Third Edition
ee
pl
C o m m u n i t y
E x p e r i e n c e
D i s t i l l e d
Sa
m
Clment Nedelcu
France, and China. After teaching computer science, programming, and systems
administration in several eastern Chinese universities, he worked as a technology
consultant in France. Here, he specialized in web and .NET software development as
well as Linux server administration. Since 2005, Clment has administered a major
network of websites in his spare time, which eventually led him to discover Nginx.
It made such a big difference that he started his own blog about it; you can find it at
http://cnedelcu.net.
Preface
It is a well-known fact that the market for web servers has a long-established
leader: Apache. According to recent surveys conducted in October 2015, almost
35 percent of the World Wide Web is served by this twenty-year old open source
application. However, the same reports reveal the rise of a new competitor in the
past few years: Nginx, a lightweight HTTP server originating from Russia and
pronounced "engine x". What has caused so many server administrators to switch to
Nginx since the beginning of the 2009? Is this tiny piece of software mature enough
to run a high-traffic website?
To begin with, Nginx is not as young as one might think. Originally started in 2002,
the project was first carried out by a standalone developer, Igor Sysoev, for the
needs of an extremely high-traffic Russian website, namely Rambler, which received,
as of September 2008, over 500 million HTTP requests per day. The application is
now used to serve some of the most popular websites on the Web, such as Reddit,
Wikipedia, WordPress, Dropbox, and many more. Nginx has proved to be a very
efficient, lightweight yet powerful web server. Throughout the chapters in this book,
you will discover the numerous features of Nginx and progressively understand
why so many administrators decide to place their trust in this new HTTP server,
often at the expense of Apache.
There are several aspects in which Nginx is more efficient than its competitors.
First, and foremost, it's faster. By making use of asynchronous sockets, Nginx does
not spawn processes as many times as it receives requests. One process per core
suffices to handle thousands of connections, leading to a much lighter CPU load and
memory consumption. Secondly, its simplicity of use is remarkable. Configuration
files are much easier to read and tweak with Nginx than with other web server
solutions, such as Apache; a couple of lines are enough to set up a complete virtual
host configuration.
Preface
Last but not least, server administrators appreciate it for its modularity. Not only
is Nginx a completely open source project released under a BSD-like license, but it
also comes with a powerful plugin system referred to as "modules". A large variety
of modules are included with the original distribution archive, and a number of
third-party ones can be downloaded online.
All in all, Nginx combines speed, efficiency, and power to provide you with the
perfect ingredients for a successful web server. It appears to be the best Apache
alternative as of today.
Module Configuration
The true power of Nginx lies within its modules. The entire application is built on
a modular system, and each module can be enabled or disabled at compile time.
Some bring up simple functionality, such as the Autoindex module that generates
a listing of the files in a directory. Others will transform your perception of a web
server (such as the Rewrite module). Developers are also invited to create their own
modules. A quick overview of the third-party module system can be found at the
end of this chapter.
This chapter covers:
The Rewrite module, which does more than just rewriting URIs
[ 101 ]
Module Configuration
Basically, the purpose of this module (as the name suggests) is to perform
URL rewriting. This mechanism allows you to get rid of ugly URLs containing
multiple parameters. For instance, http://example.com/article.
php?id=1234&comment=32such URLs are particularly uninformative and
meaningless for a regular visitor. Instead, links to your website will contain useful
information that indicates the nature of the page the visitor is about to visit. The
URL given in the example becomes http://website.com/article-1234-32-USeconomy-strengthens.html. This solution is not only more interesting for your
visitors, but also for search enginesURL rewriting is a key element of Search
Engine Optimization (SEO).
The principle behind this mechanism is simpleit consists of rewriting the URI of the
client request after it is received and before serving the file. Once rewritten, the URI is
matched against the location blocks in order to find the configuration that should be
applied to the request. The technique is further detailed in the coming sections.
Purpose
The first question we must answer is: what is the purpose of regular expressions?
To put it simply, the main purpose is to verify that a string of characters matches a
given pattern. The pattern is written in a particular language that allows the defining
of extremely complex and accurate rules.
String
Pattern
Does it
match?
Explanation
hello
^hello$
Yes
hell
^hello$
No
Hello
^hello$
Depends
[ 102 ]
Chapter 4
This concept becomes a lot more interesting when complex patterns are employed,
such as one that validates e-mail addresses: ^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.
[A-Z]{2,4}$. Programmatically validating if an e-mail address is well-formed
would require a great deal of code, while all the work can be done with a single
regular expression in pattern matching.
PCRE syntax
The syntax that Nginx employs originates from the Perl Compatible Regular
Expression (PCRE) library, which (if you remember Chapter 2, Basic Nginx
Configuration) is a pre-requisite for making your own build, unless you disable the
modules that make use of it. It's the most commonly used form of regular expressions,
and nearly everything you learn here remains valid for other language variations.
In its simplest form, a pattern is composed of one character, for example, x. We can
match strings against this pattern. Does example match the pattern x? Yes, example
contains the character x. It can be more than one specific characterthe pattern
[a-z] matches any character between a and z, or even a combination of letters and
digits: [a-z0-9]. In consequence, the pattern hell[a-z0-9] validates the following
strings: hello and hell4 but not hell or hell!.
You probably noticed that we employed the brackets [ and ]. They are part of what
we call metacharacters and have a special effect on the pattern. There are a total of
11 metacharacters, and all play a different role. If you want to create a pattern that
actually contains one of these characters, you need to escape the character with a
\ (backslash).
Metacharacter
Description
Beginning
Example pattern: ^h
Matching strings: hello, h, hh (anything beginning with h)
Non-matching strings: character, ssh
End
Example pattern: e$
Matching strings: sample, e, file (anything ending with e)
Non-matching strings: extra, shell
. (dot)
Any
Module Configuration
Metacharacter
Description
[ ]
Set
Syntax: [a-z] for a range, [abcd] for a set, and [a-z0-9] for two
ranges. Note that if you want to include the character in a range, you
need to insert it right after [ or just before ].
Example pattern: hell[a-y123-]
Matching strings: hello, hell1, hell2, hell3, hellNon-matching strings: hellz, hell4, heloo, he-llo
[^ ]
Negate set
Alternation
( )
Grouping
Escape
Quantifiers
So far, you are able to express simple patterns with a limited number of characters.
Quantifiers allow you to extend the number of accepted entities:
Quantifier
Description
0 or more times
Chapter 4
Quantifier
Description
1 or more times
0 or 1 time
{x}
x times
{x,}
At least x times
{x,y}
x to y times
As you probably noticed, the { and } characters in the regular expressions conflict
with the block delimiter of the Nginx configuration file syntax language. If you want
to write a regular expression pattern that includes curly brackets, you need to place
the pattern between quotes (single or double quotes):
rewrite hel{2,}o /hello.php; # invalid
rewrite "hel{2,}o" /hello.php; # valid
rewrite 'hel{2,}o' /hello.php; # valid
[ 105 ]
Module Configuration
Captures
One last feature of the regular expression mechanism is the ability to capture
sub-expressions. Whatever text is placed between the parentheses ( ) is captured
and can be used after the matching process. The captured characters become
available under the form of variables called $N, where N is a numeric index, in
order of capture. Alternatively, you can attribute an arbitrary name to each of your
captures (see the next example). The variables generated through the captures can
be inserted within the directive values. The following are a couple of examples that
illustrate the principle:
Pattern
Example of
a matching
string
hello sir
^(hello|hi) (sir|mister)$
Captured
$1 = hello
$2 = sir
^(hello (sir))$
hello sir
^(.*)$
^(.{1,3})([0-9]{1,4})([?!]{1,2})$
nginx rocks
abc1234!?
$1 = hello sir
$2 = sir
$1 = nginx rocks
$1 = abc
$2 = 1234
$3 = !?
/admin/doc
$folder = admin
$file = doc
^/(?<folder>[^/]+)/(?<file>.*)$
When you use a regular expression in Nginx, for example, in the context of a
location block, the buffers that you capture can be employed in later directives:
server {
server_name website.com;
location ~* ^/(downloads|files)/(.*)$ {
add_header Capture1 $1;
add_header Capture2 $2;
}
}
[ 106 ]
Chapter 4
In the preceding example, the location block will match the request URI against a
regular expression. A couple of URIs that would apply here would be /downloads/
file.txt, /files/archive.zip, or even /files/docs/report.doc. Two parts
are captured: $1 will contain either downloads or files, and $2 will contain
whatever comes after /downloads/ or /files/. Note that the add_header directive
(syntax: add_header header_name header_value, see the HTTP headers module
section) is employed here to append arbitrary headers to the client response for the
sole purpose of demonstration.
Internal requests
Nginx differentiates external and internal requests. External requests directly originate
from the client; the URI is then matched against the possible location blocks:
server {
server_name website.com;
location = /document.html {
deny all; # example directive
}
}
Internal redirects: Nginx redirects the client requests internally. The URI
is changed, and the request may therefore match another location block
and become eligible for different settings. The most common case of internal
redirects is when using the rewrite directive, which allows you to rewrite the
request URI.
Module Configuration
error_page
Detailed in the module directives of the Nginx HTTP Core module, error_page
allows you to define the server behavior when a specific error code occurs. The
simplest form is that of affecting a URI to an error code:
server {
server_name website.com;
error_page 403 /errors/forbidden.html;
error_page 404 /errors/not_found.html;
}
When a client attempts to access a URI that triggers one of these errors (such as
loading a document or a file that does not exist on the server, resulting in a 404
error), Nginx is supposed to serve the page associated with the error code. In fact,
it does not just send the client the error pageit actually initiates a completely new
request based on the new URI.
Consequently, you can end up falling back on a different configuration, like in the
following example:
server {
server_name website.com;
root /var/www/vhosts/website.com/httpdocs/;
error_page 404 /errors/404.html;
location /errors/ {
alias /var/www/common/errors/;
internal;
}
}
When a client attempts to load a document that does not exist, they will initially
receive a 404 error. We employed the error_page directive to specify that 404 errors
should create an internal redirect to /errors/404.html. As a result, a new request
is generated by Nginx with the URI /errors/404.html. This URI falls under the
location block /errors/, so the corresponding configuration applies.
Logs can prove to be particularly useful when working with redirects
and URL rewrites. Be aware that information on internal redirects will
show up in the logs only if you set the error_log directive to debug.
You can also get it to show up at the notice level, under the condition
that you specify rewrite_log on; wherever you need it.
[ 108 ]
Chapter 4
A raw but trimmed excerpt from the debug log summarizes the mechanism:
->http request line: "GET /page.html HTTP/1.1"
->http uri: "/page.html"
->test location: "/errors/"
->using configuration ""
->http filename: "/var/www/vhosts/website.com/httpdocs/page.html"
-> open() "/var/www/vhosts/website.com/httpdocs/page.html" failed (2:
No such file or directory), client: 127.0.0.1, server: website.com,
request: "GET /page.html HTTP/1.1", host:"website.com"
->http finalize request: 404, "/page.html?" 1
->http special response: 404, "/page.html?"
->internal redirect: "/errors/404.html?"
->test location: "/errors/"
->using configuration "/errors/"
->http filename: "/var/www/common/errors/404.html"
->http finalize request: 0, "/errors/404.html?" 1
Note that the use of the internal directive in the location block forbids clients
from accessing the /errors/ directory. This location can thus only be accessed
through an internal redirect.
The mechanism is the same for the index directive (detailed further on in the Index
module)if no file path is provided in the client request, Nginx will attempt to serve
the specified index page by triggering an internal redirect.
Rewrite
While the previous directive, error_page, is not actually a part of the Rewrite
module, detailing its functionality provides a solid introduction to the way Nginx
handles client requests.
Similarly to how the error_page directive redirects to another location, rewriting
the URI with the rewrite directive generates an internal redirect:
server {
server_name website.com;
root /var/www/vhosts/website.com/httpdocs/;
location /storage/ {
internal;
alias /var/www/storage/;
}
location /documents/ {
rewrite ^/documents/(.*)$ /storage/$1;
}
}
[ 109 ]
Module Configuration
Infinite loops
With all the different syntaxes and directives, you could easily get confused.
Worseyou might get Nginx confused. This happens, for instance, when your
rewrite rules are redundant, and cause internal redirects to loop infinitely:
server {
server_name website.com;
location /documents/ {
rewrite ^(.*)$ /documents/$1;
}
}
You thought you were doing well, but this configuration actually triggers internal
redirects /documents/anything to /documents//documents/anything. Moreover,
since the location patterns are re-evaluated after an internal redirect, /documents//
documents/anything becomes /documents//documents//documents/anything.
[ 110 ]
Chapter 4
You probably wonder if this goes on indefinitelythe answer is no. The number of
cycles is restricted to 10. You are only allowed 10 internal redirects. Anything past
this limit and Nginx will produce a 500 Internal Server Error.
Nginx processes these two commands; in this case, it reads the contents of header.
html and body.html and inserts them into the document source, which is then sent
to the client.
Several commands are at your disposal; they are detailed in the SSI module section
in this chapter. The one we are interested in for now is the include command for
including a file into another file:
<!--# include virtual="/footer.php?id=123" -->
[ 111 ]
Module Configuration
The specified file is not just opened and read from a static location. Instead, a whole
subrequest is processed by Nginx, and the body of the response is inserted instead of
the include tag.
Conditional structure
The Rewrite module introduces a new set of directives and blocks among which is
the if conditional structure:
server {
if ($request_method = POST) {
[]
}
}
This allows you to apply a configuration according to the specified condition. If the
condition is true, the configuration is applied; otherwise, it isn't.
The following table describes the various syntaxes accepted when forming a condition:
Operator
Description
None
The condition is true if the specified variable or data is not equal to an empty
string or a string starting with the character 0:
if ($string) {
[]
}
=, !=
The != operator does the opposite: "if the request method is not equal to
GET, then apply the configuration":
if ($request_method != GET) {
[]
}
[ 112 ]
Chapter 4
Operator
Description
~, ~*, !~,
!~*
The condition is true if the argument preceding the ~ symbol matches the
regular expression pattern placed after it:
if ($request_filename ~ "\.txt$") {
[]
}
Note that you can insert the capture buffers in the regular expression:
if ($uri ~ "^/search/(.*)$") {
set $query $1;
rewrite ^ http://google.com/search?q=$query;
}
-f, !-f
-d, !-d
-e, !-e
Similar to the f operator, is used for testing the existence of a file, directory,
or symbolic link.
-x, !-x
Similar to the f operator, is used for testing whether a file exists and is
executable.
Module Configuration
As a matter of fact, the main difference lies within the directives that can be
employed within either blocksome can be inserted in an if block and some can't;
on the contrary, almost all the directives are authorized within a location block, as
you probably noticed in the directive listings so far. In general, it's best to only insert
the directives from the Rewrite module within an if block, as other directives were
not originally intended for such usage.
Directives
The Rewrite module provides you with a set of directives that do more than just
rewriting a URI. The following table describes these directives, along with the
context in which they can be employed:
Directive
Description
rewrite
Context: server,
location, if
Chapter 4
Directive
Description
Is decoded: The URI corresponding to a request such as
http://website.com/my%20page.html would be /my
page.html (in the encoded URI, %20 indicates a white space
character).
Does not contain arguments: For a request such as http://
website.com/page.php?id=1&p=2, the URI would be
/page.php. When rewriting the URI, you don't need to
consider including the arguments in the replacement URI
Nginx does it for you. If you want Nginx not to include
the arguments after the rewritten URI, you must insert a ?
character at the end of the replacement URI: rewrite ^/
search/(.*)$ /search.php?q=$1?.
Examples:
rewrite
rewrite
rewrite
rewrite
break
Context: server,
location, if
^/search/(.*)$ /search.php?q=$1;
^/search/(.*)$ /search.php?q=$1?;
^ http://website.com;
^ http://website.com permanent;
[ 115 ]
Module Configuration
Directive
Description
return
Context: server,
location, if
set
Context: server,
location, if
uninitialized_
variable_warn
If set to on, Nginx will issue log messages when the configuration
employs a variable that has not yet been initialized.
Context: http,
server,
location, if
Syntax: on or off
rewrite_log
If set to on, Nginx will issue log messages for every operation
performed by the rewrite engine at the notice error level (see
error_log directive).
Context: http,
server,
location, if
uninitialized_variable_warn on;
Syntax: on or off
Default value: off
rewrite_log off;
[ 116 ]
Chapter 4
Performing a search
This rewrite rule is intended for search queries. Search keywords are included in
the URL.
Input URI
http://website.com/search/some-search-keywords
Rewritten URI
http://website.com/search.php?q=some-search-keywords
Rewrite rule
http://website.com/user/31/James
Rewritten URI
http://website.com/user.php?id=31&name=James
Rewrite rule
Multiple parameters
Some websites may use different syntaxes for the argument string, for example,
separating non-named arguments with slashes.
Input URI
http://website.com/index.php/param1/param2/param3
Rewritten URI
http://website.com/index.php?p1=param1&p2=param2&p3=p
aram3
rewrite ^/index.php/(.*)/(.*)/(.*)$ /index.
php?p1=$1&p2=$2&p3=$3?;
Rewrite rule
[ 117 ]
Module Configuration
Wikipedia-like
Many websites have now adopted the URL style introduced by Wikipedia: a prefix
folder, followed by an article name.
Input URI
http:// website.com/wiki/Some_keyword
Rewritten URI
http://website.com/wiki/index.php?title=Some_keyword
Rewrite rule
http://website.com/33526/us-economy-strengthens
Rewritten URI
http://website.com/article.php?id=33526
Rewrite rule
Discussion board
Modern bulletin boards now mostly use pretty URLs. The following example shows
how to create a topic view URL with two parametersthe topic identifier and the
starting post. Once again, keywords are ignored:
Input URI
http://website.com/topic-1234-50-some-keywords.html
Rewritten URI
http://website.com/viewtopic.php?topic=1234&start=50
Rewrite rule
rewrite ^/topic-([0-9]+)-([0-9]+)-(.*)\.html$ /
viewtopic.php?topic=$1&start=$2?;
[ 118 ]
Chapter 4
SSI module
SSI or Server Side Includes, is actually a sort of server-side programming language
interpreted by Nginx. Its name originates from the fact that the most-used functionality
of the language is the include command. Back in the 1990s, such languages were
employed in order to render web pages dynamically, from simple static .html files
with client-side scripts to complex pages with server-processed instructions. Within
the HTML source code, webmasters could now insert server-interpreted directives,
which would then lead the way to much more advanced pre-processors such as PHP
or ASP.
The most famous illustration of SSI is the quote of the day example. In order to insert
a new quote every day at the top of each page of their website, webmasters would
have to edit out the HTML source of every page of the site, updating the old quote
manually. With Server Side Includes, a single command suffices to simplify the task:
<html>
<head><title>My web page</title></head>
<body>
<h1>Quote of the day: <!--# include file="quote.txt" -->
</h1>
</body>
</html>
All you would have to do to update the quote is to edit the contents of the quote.
txt file. Automatically, all the pages would show the updated quote. As of today,
most of the major web servers (Apache, IIS, Lighttpd, and so on) support Server
Side Includes.
[ 119 ]
Module Configuration
Description
ssi
Syntax: on or off
Default value: off
ssi on;
ssi_types
Context: http, server,
location
Defines the MIME file types that should be eligible for SSI
parsing. The text/html type is always included.
Syntax:
ssi_types type1 [type2] [type3...];
ssi_types *;
ssi_silent_errors
Context: http, server,
location
ssi_value_length
Context: http, server,
location
[ 120 ]
Chapter 4
Directive
Description
ssi_ignore_
recycled_buffers
When set to on, this directive prevents Nginx from making use
of the recycled buffers.
Syntax: on or off
ssi_min_file_chunk
Default: off
A quick note regarding possible concerns about the SSI engine resource usageby
enabling the SSI module at the location or server block level, you enable parsing
of at least all text/html files (pretty much any page to be displayed by the client
browser). While the Nginx SSI module is efficiently optimized, you might want to
disable parsing for the files that do not require it.
Firstly, all your pages containing the SSI commands should have the .shtml
(Server HTML) extension. Then, in your configuration at the location block level,
enable the SSI engine under a specific condition. The name of the served file must
end with .shtml:
server {
server_name website.com;
location ~* \.shtml$ {
ssi on;
}
}
On one hand, all HTTP requests submitted to Nginx will go through an additional
regular expression pattern matching. On the other hand, static HTML files or files to be
processed by other interpreters (.php, for instance) will not be parsed unnecessarily.
[ 121 ]
Module Configuration
$date_gmt: Returns the current GMT time, regardless of the server time zone
time zone
SSI commands
Once you have the SSI engine enabled for your web pages, you are ready to start
writing your first dynamic HTML page. Again, the principle is simpledesign the
pages of your website using the regular HTML code, inside which you will insert the
SSI commands.
These commands respect a particular syntaxat first sight, they look like regular
HTML comments: <!-- A comment -->, and that is the good thing about itif you
accidentally disable SSI parsing of your files, the SSI commands do not appear on the
client browser; they are only visible in the source code as actual HTML comments.
The full syntax is as follows:
<!--# command param1="value1" param2="value2" -->
File includes
The main command of the Server Side Include module is, obviously, the include
command. It can be used in two different fashions.
First, you are allowed to make a simple file include:
<!--# include file="header.html" -->
This also sends a sub-request to the server; the difference lies in the way that
Nginx fetches the specified file (when using include file, the wait parameter is
automatically enabled). Indeed, two parameters can be inserted within the include
command tag. By default, all SSI requests are issued simultaneously, in parallel. This
can cause slowdowns and timeouts in case of heavy loads. Alternatively, you can use
the wait="yes" parameter to specify that Nginx should wait for the completion of
the request before moving on to other includes:
<!--# include virtual="header.php" wait="yes" -->
[ 122 ]
Chapter 4
As you can see, the contents of the error_footer block were inserted at the location
of the include command, after the <h1> tag.
[ 123 ]
Module Configuration
var: The name of the variable that you want to display, for example,
REMOTE_ADDR to display the IP address of the client.
encoding: Encoding method for the string. The accepted values are none (no
particular encoding), url (encode text like a URLa blank space becomes
%20, and so on), and entity (uses HTML entities: & becomes &).
You may also affect your own variables with the set command:
<!--# set var="my_variable" value="your value here" -->
The value parameter is itself parsed by the engine; as a result, you are allowed to
make use of the existing variables:
<!--#
<!--#
<!--#
<!--#
<!--#
The following is the output that Nginx displays for each of the three echo commands
from the preceding example:
(none)
hello
hello there
Conditional structure
The following set of commands allow you to include text or other directives
depending on a condition. The conditional structure can be established with
the following syntax:
<!--# if expr="expression1" -->
[]
<!--# elif expr="expression2" -->
[ 124 ]
Chapter 4
[]
<!--# else -->
[]
<!--# endif -->
The content that you insert within a condition block can contain regular HTML code
or additional SSI directives with one exceptionyou cannot nest if blocks.
Configuration
Last and probably the least (for once) of the SSI commands offered by Nginx is the
config command. It allows you to configure two simple parameters.
First, the message that appears when the SSI engine faces an error related to
malformed tags or invalid expressions. By default, Nginx displays [an error
occurred while processing the directive]. If you want it to display
something else, enter the following:
<!--# config errmsg="Something terrible happened" -->
Additionally, you can configure the format of the dates that are returned by the
$date_local and $date_gmt variables using the timefmt parameter:
<!--# config timefmt="%A, %d-%b-%Y %H:%M:%S %Z" -->
The string that you specify here is passed as the format string of the strftime C
function. For more information about the arguments that can be used in the format
string, please refer to the documentation of the strftime C language function at
http://www.opengroup.org/onlinepubs/009695399/functions/strftime.html.
[ 125 ]
Module Configuration
Additional modules
The first half of this chapter covered two of the most important Nginx modules: the
Rewrite module and the SSI module. There are a lot more modules that will greatly
enrich the functionality of the web server; they are regrouped here, thematically.
Among the modules described in this section, some are included in the default
Nginx build, but some are not. This implies that unless you specifically configured
your Nginx build to include these modules (as described in Chapter 1, Downloading
and Installing Nginx), they will not be available to you. But remember that rebuilding
Nginx to include additional modules is a relatively quick and easy process.
Index
The Index module provides a simple directive named index, which lets you define
the page that Nginx will serve by default if no filename is specified in the client
request (in other words, it defines the website index page). You may specify multiple
filenames; the first file to be found will be served. If none of the specified files are
found, Nginx will either attempt to generate an automatic index of the files (if the
autoindex directive is enabledcheck the HTTP Autoindex module), or return a
403 Forbidden error page.
Optionally, you may insert an absolute filename (such as /page.html), but only as
the last argument of the directive.
Syntax: index file1 [file2] [absolute_file];
Default value: index.html
index index.php index.html index.htm;
index index.php index2.php /catchall.php;
This directive is valid in the following contexts: http, server, and location.
Autoindex
If Nginx cannot provide an index page for the requested directory, the default
behavior is to return a 403 Forbidden HTTP error page. With the following set
of directives, you enable an automatic listing of the files that are present in the
requested directory:
[ 126 ]
Chapter 4
Three columns of information appear for each filethe filename, the file date and
time, and the file size in bytes.
Directive
Description
autoindex
Syntax: on or off
If set to on, this directive ensures that the listing displays the
file sizes in bytes. Otherwise, another unit is employed, such as
KB, MB, or GB.
Syntax: on or off
Default value: on
autoindex_localtime
Context: http, server,
location
autoindex_format
Context: http, server,
location
[ 127 ]
Module Configuration
Random index
This module enables a simple directive, random_index, which can be used within a
location block for Nginx to return an index page selected randomly among the files
of the specified directory.
This module is not included in the default Nginx build.
Syntax: on or off
Log
This module controls the behavior of Nginx regarding the access logs. It is a key
module for system administrators, as it allows analyzing the runtime behavior of
web applications. It is composed of three essential directives:
Directive
Description
access_log
This parameter defines the access log file path, the format
of entries in the access log by selecting a template name, or
disables access logging.
[ 128 ]
Chapter 4
Directive
Description
log_format
open_log_file_
cache
Context: http, server,
location
Configures the cache for log file descriptors. Please refer to the
open_file_cache directive of the HTTP Core module for
additional information.
Syntax: open_log_file_cache max=N [inactive=time]
[min_uses=N] [valid=time] | off;
The arguments are similar to the open_file_cache and other
related directives; the difference is that this applies to access log
files only.
The Log module also enables several new variables, though they are only accessible
when writing log entries:
$time_local: Local time (at the time of writing the log entry)
$msec: Local time (at the time of writing the log entry) to the microsecond
$body_bytes_sent: Number of bytes sent to the client for the response body
[ 129 ]
Module Configuration
Auth_basic module
The auth_basic module enables the basic authentication functionality. With the
two directives that it brings forth, you can make it such that a specific location of
your website (or your server) is restricted to users who authenticate with a username
and password:
location /admin/ {
auth_basic "Admin control panel"; # variables are supported
auth_basic_user_file access/password_file;
}
The first directive, auth_basic, can be set to either off or a text message, usually
referred to as authentication challenge or authentication realm. This message is displayed
by the web browsers in a username/password box when a client attempts to access
the protected resource.
The second one, auth_basic_user_file, defines the path of the password file relative
to the directory of the configuration file. A password file is formed of lines respecting
the following syntax: username:[{SCHEME}]password[:comment]. Where:
If you fail to specify a scheme, the password will need to be encrypted with the
crypt(3) function, for example with the help of the htpasswd command-line utility
[ 130 ]
Chapter 4
Access
Two important directives are brought up by this module: allow and deny. They let
you allow or deny access to a resource for a specific IP address or IP address range.
Both directives have the same syntax: allow IP | CIDR | unix: | all, where
IP is an IP address, CIDR is an IP address range (CIDR syntax), unix: represents all
UNIX domain sockets, and all specifies that the directive applies to all clients:
location {
allow 127.0.0.1; # allow local IP address
allow unix:; # allow UNIX domain sockets
deny all; # deny all other IP addresses
}
Note that rules are processed from top-downif your first instruction is deny all,
all possible allow exceptions that you place afterwards will have no effect. The
opposite is also trueif you start with allow all, all possible deny directives that
you place afterwards will have no effect, as you already allowed all the IP addresses.
Limit connections
The mechanism induced by this module is a little more complex than the regular
ones. It allows you to define the maximum number of simultaneous connections to
the server for a specific zone.
The first step is to define the zone using the limit_conn_zone directive:
$variable is the variable that will be used to differentiate one client from
another, typically $binary_remote_addrthe IP address of the client in the
size is the maximum size you allocate to the table storing session states
The following example defines the zones based on the client IP addresses:
limit_conn_zone $binary_remote_addr zone=myzone:10m;
Now that you have defined a zone, you may limit the connections using limit_conn:
limit_conn zone_name connection_limit;
[ 131 ]
Module Configuration
As a result, requests that share the same $binary_remote_addr are subject to the
connection limit (one simultaneous connection). If the limit is reached, all additional
concurrent requests will be answered with a 503 Service unavailable HTTP
response. This response code can be overridden if you specify another code via the
limit_conn_status directive. If you wish to log client requests that are affected by
the limits you have set, enable the limit_conn_log_level directive, and specify the
log level (info | notice | warn | error).
Limit request
In a similar fashion, the Limit request module allows you to limit the number of
requests for a defined zone.
Defining the zone is done via the limit_req_zone directive; its syntax differs from
the Limit zone equivalent directive:
limit_req_zone $variable zone=name:max_memory_size rate=rate;
The directive parameters are identical except for the trailing rate: expressed in
requests per second (r/s) or requests per minute (r/m). It defines a request rate that
will be applied to clients where the zone is enabled. To apply a zone to a location,
use the limit_req directive:
limit_req zone=name burst=burst [nodelay];
The burst parameter defines the maximum possible bursts of requestswhen the
amount of requests received from a client exceeds the limit defined in the zone,
the responses are delayed in a manner that respects the rate that you defined. To a
certain extent, only a maximum of burst requests will be accepted simultaneously.
Past this limit, Nginx returns a 503 Service Unavailable HTTP error response.
This response code can be overridden if you specify another code via the limit_
req_status directive.
limit_req_zone $binary_remote_addr zone=myzone:10m rate=2r/s;
[]
location /downloads/ {
limit_req zone=myzone burst=10;
limit_req_status 404; # returns a 403 error if limit is exceeded
}
[ 132 ]
Chapter 4
If you wish to log client requests that are affected by the limits you have set, enable
the limit_req_log_level directive, and specify the log level (info | notice |
warn | error).
Auth_request
The auth_request module was implemented in the recent versions of Nginx, and
allows you to allow or deny access to a resource based on the result of a sub-request.
Nginx calls the URI that you specify via the auth_request directive: if the subrequest returns a 2XX response code (that is, HTTP/200 OK), access is allowed. If the
sub-request returns a 401 or 403 status code, access is denied, and Nginx forwards
the response code to the client. Should the backend return any other response code,
Nginx will consider it to be an error and deny access to the resource.
location /downloads/ {
# if the script below returns a 200 status code,
# the download is authorized
auth_request /authorization.php;
}
[ 133 ]
Module Configuration
Empty GIF
The purpose of this module is to provide a directive that serves a 1 x 1 transparent
GIF image from the memory. Such files are sometimes used by web designers to
tweak the appearance of their website. With this directive, you get an empty GIF
straight from the memory instead of reading and processing an actual GIF file from
the storage space.
To utilize this feature, simply insert the empty_gif directive in the location of
your choice:
location = /empty.gif {
empty_gif;
}
To utilize this feature, simply insert the flv or mp4 directive in the location of
your choice:
location ~* \.flv {
flv;
}
location ~* \.mp4 {
mp4;
}
Be aware that in case Nginx fails to seek the requested position within the video file,
the request will result in a 500 Internal Server Error HTTP response. JWPlayer
sometimes misinterprets this error, and simply displays a Video not found error message.
[ 134 ]
Chapter 4
HTTP headers
Two directives are introduced by this module that affect the header of the response
sent to the client.
First, add_header Name value [always] lets you add a new line in the response
headers, respecting the following syntax: Name: value. The line is added only for
responses with the following codes: 200, 201, 204, 301, 302, and 304. You may insert
variables in the value argument. If you specify always at the end of the directive
value, the header will always be added regardless of the response code.
Additionally, the expires directive allows you to control the value of the Expires and
Cache-Control HTTP header sent to the client, affecting the requests of the codes listed
previously. It accepts a single value among the following:
A time value: The expiration date of the file is set to the current time +, the time
you specify. For example, expires 24h will return an expiry date set to 24
hours from now
epoch: The expiration date of the file is set to January 1, 1970. The CacheControl header is set to no-cache
max: The expiration date of the file is set to December 31, 2037. The Cache-
Addition
The Addition module allows you (through simple directives) to add content before
or after the body of the HTTP response.
This module is not included in the default Nginx build.
As stated previously, Nginx triggers a sub-request for fetching the specified URI.
Additionally, you can define the type of files to which the content is appended in
case your location block pattern is not specific enough (default: text/html):
addition_types mime_type1 [mime_type2];
addition_types *;
[ 135 ]
Module Configuration
Substitution
Along the same lines as that of the preceding module, the Substitution module
allows you to search and replace text directly from the response body:
sub_filter searched_text replacement_text;
sub_filter_once (on or off, default on): Only replaces the text once, and
Gzip filter
This module allows you to compress the response body with the Gzip algorithm before
sending it to the client. To enable Gzip compression, use the gzip directive (on or off)
at the http, server, location, and even the if level (though that is not recommended).
The following directives will help you further configure the filter options:
Directive
Description
gzip_buffers
Defines the number and size of buffers to be used for storing the
compressed response.
Context: http,
server, location
gzip_comp_level
Context: http,
server, location
gzip_disable
Context: http,
server, location
[ 136 ]
Chapter 4
Directive
gzip_http_
version
Context: http,
server, location
gzip_min_length
Context: http,
server, location
Description
Enables Gzip compression for the specified protocol version.
Syntax: 1.0 or 1.1
Default: 1.1
If the response body length is inferior to the specified value, it is
not compressed.
Syntax: Numeric value (size)
Default: 0
gzip_proxied
Context: http,
server, location
gzip_types
Context: http,
server, location
Context: http,
server, location
Syntax: on or off
Default: off
[ 137 ]
Module Configuration
Directive
Description
gzip_window
Context: http,
server, location
postpone_
gzipping
Context: http,
server, location
gzip_no_buffer
Context: http,
server, location
Default: 0
Syntax: on or off
Default: off
Gzip static
This module adds a simple functionality to the Gzip filter mechanismwhen its
gzip_static directive (on, off, or always) is enabled, Nginx will automatically
look for a .gz file corresponding to the requested document before serving it. This
allows Nginx to send pre-compressed documents instead of compressing documents
on the fly at each request. Specifying always will force Nginx to serve the gzip
version regardless of whether the client accepts gzip encoding.
This module is not included in the default Nginx build.
[ 138 ]
Chapter 4
Gunzip filter
With the Gunzip filter module, you can decompress a gzip-compressed response
sent from the backend in order to serve it raw to the client. For example, in cases
where the client browser is not able to process the gzipped files (Microsoft Internet
Explorer 6), simply insert gunzip on; in a location block to employ this module.
You can also set the buffer amount and size with gunzip_buffers amount size;
where amount is the amount of buffers to allocate, and size is the size of each
allocated buffer.
Charset filter
With the Charset filter module, you can control the character set of the response
body more accurately. Not only are you able to specify the value of the charset
argument of the Content-Type HTTP header (such as Content-Type: text/html;
charset=utf-8), but Nginx can also re-encode the data to a specified encoding
method automatically.
Directive
Description
charset
Context: http,
server, location,
if
source_charset
Context: http,
server, location,
if
override_
charset
Context: http,
server, location,
if
charset_types
Context: http,
server, location
Syntax:
charset_types mime_type1 [mime_type2];
charset_types * ;
Module Configuration
Directive
Description
charset_map
Lets you define character re-encoding tables. Each line of the table
contains two hexadecimal codes to be exchanged. You will find reencoding tables for the koi8-r character set in the default Nginx
configuration folder (koi-win and koi-utf).
Context: http
Memcached
Memcached is a daemon application that can be connected to via sockets. Its main
purpose, as the name suggests, is to provide an efficient distributed key/value
memory caching system. The Nginx Memcached module provides directives allowing
you to configure access to the Memcached daemon.
Directive
Description
memcached_pass
Context: location, if
memcached_bind
Context: http, server, location
memcached_connect_timeout
Context: http, server, location
memcached_send_timeout
Context: http, server, location
memcached_read_timeout
Context: http, server, location
memcached_buffer_size
Context: http, server, location
[ 140 ]
Chapter 4
Directive
memcached_next_upstream
Context: http, server, location
Description
When the memcached_pass directive is connected
to an upstream block (refer to the section on
upstream module), this directive defines the
conditions that should be matched in order to skip
to the next upstream server.
Syntax: Values selected among error timeout,
invalid_response, not_found, or off
Default: error timeout
Example: memcached_next_upstream off;
memcached_gzip_flag
Context: http, server, location
Additionally, you will need to define the $memcached_key variable, which defines
the key of the element that you are placing or fetching from the cache. You may, for
instance, use set $memcached_key $uri or set $memcached_key $uri?$args.
Note that the Nginx Memcached module is only able to retrieve data from the cache;
it does not store the results of requests. Storing data in the cache should be done
by a server-side script. You just need to make sure to employ the same key-naming
scheme in both your server-side scripts and the Nginx configuration. As an example,
we could decide to use memcached to retrieve data from the cache before passing the
request to a proxy if the requested URI is not found (see Chapter 7, From Apache to
Nginx, for more details about the Proxy module):
server {
server_name example.com;
[]
location / {
set $memcached_key $uri;
memcached_pass 127.0.0.1:11211;
error_page 404 @notcached;
}
location @notcached {
internal;
[ 141 ]
Module Configuration
# if the file is not found, forward request to proxy
proxy_pass 127.0.0.1:8080;
}
}
Image filter
This module provides image processing functionalities through the GD Graphics
Library (also known as gdlib).
This module is not included in the default Nginx build.
Make sure to employ the following directives on a location block that filters image
files only, such as location ~* \.(png|jpg|gif)$ { }.
Directive
Description
image_filter
Context: location
image_filter_
buffer
Context: http, server,
location
[ 142 ]
Chapter 4
Directive
image_filter_jpeg_
quality
Context: http, server,
location
image_filter_
transparency
Context: http, server,
location
Description
Defines the quality of the output JPEG images.
Default: image_filter_jpeg_quality 75;
image_filter_
sharpen
image_filter_
interlace
Syntax: on or off
Default: 0
Default: off
Please note that when it comes to JPG images, Nginx automatically strips off the
metadata (such as EXIF) if it occupies more than five percent of the total space
of the file.
XSLT
The Nginx XSLT module allows you to apply an XSLT transform on an XML file or
response received from a backend server (proxy, FastCGI, and so on) before serving
the client.
This module is not included in the default Nginx build
Directive
Description
xml_entities
Context: http,
server, location
Module Configuration
Directive
Description
xslt_stylesheet
Specifies the XSLT template file path with its parameters. Variables
may be inserted in the parameters.
Context: location
xslt_types
Context: http,
server, location
xslt_paramxslt_
string_param
Context: http,
server, location
Browser
The Browser module parses the User-Agent HTTP header of the client request
in order to establish values for the variables that can be employed later in the
configuration. The three variables produced are:
directive.
[ 144 ]
Chapter 4
To help Nginx recognize the web browsers and for telling the old from the modern,
you need to insert multiple occurrences of the ancient_browser and modern_browser
directives:
modern_browser opera 10.0;
With this example, if the User-Agent HTTP header contains Opera 10.0, the client
browser is considered modern.
Map
Just like the Browser module, the Map module allows you to create maps of values
depending on a variable:
map $uri $variable {
/page.html 0;
/contact.html 1;
/index.html 2;
default 0;
}
rewrite ^ /index.php?page=$variable;
Note that the map directive can only be inserted within the http block. Following this
example, $variable may have three different values. If $uri was set to /page.html,
$variable is now defined as 0; if $uri was set to /contact.html, $variable is
now 1; if $uri was set to /index.html, $variable now equals 2. For all other cases
(default), $variable is set to 0. The last instruction rewrites the URL accordingly.
Apart from default, the map directive accepts another special keyword: hostnames.
It allows you to match the hostnames using wildcards such as *.domain.com.
Two additional directives allow you to tweak the way Nginx manages the
mechanism in memory:
map_hash_max_size: Sets the maximum size of the hash table holding a map
Regular expressions may also be used in patterns if you prefix them with ~ (case
sensitive) or ~* (case insensitive):
map $http_referer $ref {
~google "Google";
~* yahoo "Yahoo";
\~bing "Bing"; # not a regular expression due to the \ before the
tilde
default $http_referer; # variables may be used
}
[ 145 ]
Module Configuration
Geo
The purpose of this module is to provide a functionality that is quite similar to
the map directiveaffecting a variable based on the client data (in this case, the IP
address). The syntax is slightly different in that you are allowed to specify IPv4 and
IPv6 address ranges (in CIDR format):
geo $variable {
default unknown;
127.0.0.1
local;
123.12.3.0/24 uk;
92.43.0.0/16 fr;
}
Note that the preceding block is being presented to you just for the sake of the
example and does not actually detect U.K. and French visitors; you'll have to use the
GeoIP module if you wish to achieve proper geographical location detection. In this
block, you may insert a number of directives that are specific to this module:
delete: Allows you to remove the specified subnetwork from the mapping.
default: The default value given to $variable in case the user's IP address
does not match any of the specified IP ranges.
ranges: If you insert this directive as the first line of your geo block, it allows
you to specify IP ranges instead of CIDR masks. The following syntax is thus
permitted: 127.0.0.1-127.0.0.255
LOCAL;
GeoIP
Although the name suggests some similarities with the previous one, this optional
module provides accurate geographical information about your visitors by making
use of the MaxMind (http://www.maxmind.com) GeoIP binary databases. You need
to download the database files from the MaxMind website and place them in your
Nginx directory.
[ 146 ]
Chapter 4
All you have to do then is specify the database path with one of the following
directives:
geoip_country country.dat; # country information db
geoip_city city.dat; # city information db
geoip_org geoiporg.dat; # ISP/organization db
UserID filter
This module assigns an identifier to the clients by issuing cookies. The identifier can
be accessed from the variables $uid_got and $uid_set further in the configuration.
Directive
Description
userid
[ 147 ]
Module Configuration
Directive
Description
userid_service
userid_name
userid_domain
userid_path
userid_expires
userid_p3p
Default value: /
Referer
A simple directive is introduced by this module: valid_referers. Its purpose is to
check the Referer HTTP header from the client request, and possibly, to deny access
based on the value. If the referer is considered invalid, $invalid_referer is set to 1.
In the list of valid referers, you may employ three kinds of values:
Following the definition of the $invalid_referer variable, you may, for example,
return an error code if the referer was found invalid:
valid_referers none blocked *.website.com *.google.com;
if ($invalid_referer) {
return 403;
}
[ 148 ]
Chapter 4
Be aware that spoofing the Referer HTTP header is a very simple process, so
checking the referer of client requests should not be used as a security measure.
Two more directives are offered by this module: referer_hash_bucket_size and
referer_hash_max_size, which allow you to define the bucket size and maximum
size of the valid referers hash tables respectively.
Real IP
This module provides one simple featureit replaces the client IP address by
the one specified in the X-Real-IP HTTP header for clients that visit your website
behind a proxy, or for retrieving IP addresses from the proper header if Nginx is
used as a backend server (it essentially has the same effect as Apache's mod_rpaf; see
Chapter 7, From Apache to Nginx, for more details). To enable this feature, you need to
insert the real_ip_header directive that defines the HTTP header to be exploited
either X-Real-IP or X-Forwarded-For. The second step is to define the trusted IP
addresses, in other words, the clients that are allowed to make use of those headers.
This can be done thanks to the set_real_ip_from directive, which accepts both IP
addresses and CIDR address ranges:
real_ip_header X-Forwarded-For;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 127.0.0.1;
set_real_ip_from unix:; # trusts all UNIX-domain sockets
Split Clients
The Split Clients module provides a resource-efficient way to split the visitor base
into subgroups based on the percentages that you specify. To distribute the visitors
into one group or another, Nginx hashes a value that you provide (such as the
visitor's IP address, cookie data, query arguments, and so on), and decides which
group the visitor should be affected to. The following example configuration divides
the visitors into three groups based on their IP address. If a visitor is affected to the
first 50 percent, the value of $variable will be set to group1:
split_clients "$remote_addr" $variable {
50% "group1";
30% "group2";
20% "group3";
}
[ 149 ]
Module Configuration
location ~ \.php$ {
set $args "${query_string}&group=${variable}";
}
SSL
The SSL module enables HTTPS support, HTTP over SSL/TLS in particular. It gives
you the option to serve secure websites by providing a certificate, a certificate key,
and other parameters defined with the following directives:
This module is not included in the default Nginx build.
Directive
ssl
Context: http, server
Description
Enables HTTPS for the specified server. This directive is
the equivalent of listen 443 ssl or listen port
ssl more generally.
Syntax: on or off
Default: ssl off;
ssl_certificate
ssl_certificate_key
ssl_client_certificate
ssl_crl
Context: http, server
ssl_dhparam
[ 150 ]
Chapter 4
Directive
ssl_protocols
Description
ssl_prefer_server_
ciphers
Syntax: on or off
Default: off
ssl_verify_client
Context: http, server
ssl_verify_depth
Context: http, server
ssl_session_cache
ssl_session_timeout
Context: http, server
[ 151 ]
Module Configuration
Directive
ssl_password_phrase
Context: http, server
Description
Specifies a file containing the passphrases for secret
keys. Each passphrase is specified on a separate line;
they are tried one after the other when loading a
certificate key.
Syntax: file name
Default: (none)
ssl_buffer_size
ssl_session_tickets
Context: http, server
ssl_session_ticket_key
Context: http, server
Sets the path of the key file used to encrypt and decrypt
the TLS session tickets. By default, a random value is
generated.
Syntax: file name
Default: (none)
ssl_trusted_certificate
Context: http, server
successfully verified
[ 152 ]
Chapter 4
A .key file generated with the following command: openssl genrsa -out
secure.website.com.key 1024 (other encryption levels work too).
A .csr file generated with the following command: openssl req -new
-key secure.website.com.key -out secure.website.com.csr.
The first step is to merge your website certificate and the CA certificate together with
the following command:
cat secure.website.com.crt gd_bundle.crt > combined.crt
You are then ready to configure Nginx for serving secure content:
server {
listen 443;
server_name secure.website.com;
ssl on;
ssl_certificate /path/to/combined.crt;
ssl_certificate_key /path/to/secure.website.com.key;
[]
}
[ 153 ]
Module Configuration
SSL Stapling
SSL Stapling, also called Online Certificate Status Protocol (OCSP) Stapling, is a
technique that allows clients to easily connect and resume sessions to an SSL/TLS
server without having to contact the Certificate Authority, thus reducing the SSL
negotiation time. In normal OCSP transactions, the client normally contacts the
Certificate Authority so as to check the revocation status of the server's certificate.
In the case of high traffic websites, this can cause a huge stress on the CA servers.
An intermediary solution was designedStapling. The OCSP record is obtained
periodically from the CA by your server itself, and is stapled to exchanges with the
client. The OCSP record is cached by your server for a period of up to 48 hours in
order to limit communications with the CA.
Enabling SSL Stapling should thus speed up the communication between your
visitors and your server. Achieving this in Nginx is relatively simple: all you really
need is to insert three directives in your server block, and obtain a full trusted
certificate chain file (containing both the root and intermediate certificates) from
your CA.
by the server
Two optional directives also exist, which allow you to modify the behavior of
this module:
If you are having issues connecting to the OCSP responder, make sure your Nginx
configuration contains a valid DNS resolver (using the resolver directive).
[ 154 ]
Chapter 4
SPDY
The SPDY module offers support for the SPDY protocol (the SPDY module is
not included by default). You can enable SPDY on your server by appending the
keyword spdy at the end of your listen directive.
server {
listen 443 ssl spdy;
[]
}
Due to the nature of SPDY, it can only be enabled over SSL. Two directives and two
variables are brought in by this module:
$spdy: this variable contains the SPDY protocol version if SPDY is used, an
Secure link
Totally independent from the SSL module, Secure link provides basic protection by
checking the presence of a specific hash in the URL before allowing the user to access
a resource:
location /downloads/ {
secure_link_md5 "secret";
secure_link $arg_hash,$arg_expires;
if ($secure_link = "") {
return 403;
}
}
[ 155 ]
Module Configuration
Stub status
The Stub status module was designed to provide information about the current state
of the server, such as the amount of active connections, the total handled requests,
and more. To activate it, place the stub_status directive in a location block. All
requests matching the location block will produce the status page:
location = /nginx_status {
stub_status on;
allow 127.0.0.1; # you may want to protect the information
deny all;
}
It's interesting to note that there are several server monitoring solutions, such as
Monitorix, that offer Nginx support through the Stub status page by calling it at
regular intervals and parsing the statistics.
[ 156 ]
Chapter 4
Degradation
The HTTP Degradation module configures your server to return an error page when
your server runs low on memory. It works by defining a memory amount that is to
be considered low, and then specifies the locations for which you wish to enable the
degradation check:
degradation sbrk=500m; # to be inserted at the http block level
degrade 204; # in a location block, specify the error code (204 or
444) to return in case the server condition has degraded
Google-perftools
This module interfaces the Google Performance Tools profiling mechanism for the
Nginx worker processes. The tool generates a report based on the performance
analysis of the executable code. More information can be discovered from the official
website of the project http://code.google.com/p/google-perftools/.
This module is not included in the default Nginx build.
In order to enable this feature, you need to specify the path of the report file that will
be generated using the google_perftools_profiles directive:
google_perftools_profiles logs/profiles;
WebDAV
WebDAV is an extension of the well-known HTTP protocol. While HTTP was
designed for visitors to download resources from a website (in other words, reading
data), WebDAV extends the functionality of web servers by adding write operations
such as creating files and folders, moving and copying files, and more. The Nginx
WebDAV module implements a small subset of the WebDAV protocol:
This module is not included in the default Nginx build.
Directive
Description
dav_methods
Module Configuration
Directive
Description
dav_access
create_full_put_
path
Context: http, server,
location
min_delete_depth
Context: http, server,
location
Third-party modules
The Nginx community has been growing larger over the past few years, and
many additional modules have been written by third-party developers. These
can be downloaded from the official wiki website http://wiki.nginx.org/
nginx3rdPartyModules.
The currently available modules offer a wide range of new possibilities, among
which are the following:
The Headers More module, which improves flexibility with HTTP headers,
by Yichun Zhang (agentzh)
[ 158 ]
Chapter 4
To integrate a third-party module into your Nginx build, you need to follow these
three simple steps:
1. Download the .tar.gz archive associated with the module that you wish
to download.
2. Extract the archive with the following command: tar xzf module.tar.gz.
3. Configure your Nginx build with the following command:
./configure --add-module=/module/source/path []
Once you have finished building and installing the application, the module is
available just like a regular Nginx module with its directives and variables.
If you are interested in writing Nginx modules yourself, Evan Miller published an
excellent walkthrough: Emiller's Guide to Nginx Module Development. The complete
guide may be consulted from his personal website at http://www.evanmiller.org/.
Summary
All throughout this chapter, we have discovered modules that help you in improving
or fine-tuning the configuration of your web server. Nginx fiercely stands up to other
concurrent web servers in terms of functionality, and its approach towards virtual
hosts and the way they are configured will probably convince many administrators
to make the switch.
Three additional modules were left out though. The FastCGI module will be
approached in the next chapter, as it will allow us to configure a gateway to
applications such as PHP or Python. The second one, the proxy module, which
lets us design complex setups, will be described in Chapter 7, From Apache to Nginx.
Finally, The upstream module will be detailed in Chapter 8, Introducing Load Balancing
and Optimization.
[ 159 ]
www.PacktPub.com
Stay Connected: