Book Image

Nginx Troubleshooting

By : Alexey Kapranov
Book Image

Nginx Troubleshooting

By: Alexey Kapranov

Overview of this book

Nginx is clearly winning the race to be the dominant software to power modern websites. It is fast and open source, maintained with passion by a brilliant team. This book will help you maintain your Nginx instances in a healthy and predictable state. It will lead you through all the types of problems you might encounter as a web administrator, with a special focus on performance and migration from older software. You will learn how to write good configuration files and will get good insights into Nginx logs. It will provide you solutions to problems such as missing or broken functionality and also show you how to tackle performance issues with the Nginx server. A special chapter is devoted to the art of prevention, that is, monitoring and alerting services you may use to detect problems before they manifest themselves on a big scale. The books ends with a reference to error and warning messages Nginx could emit to help you during incident investigations.
Table of Contents (15 chapters)
Nginx Troubleshooting
About the Author
About the Reviewers
Rare Nginx Error Messages

Introducing basic configuration syntax, directives, and testing

Igor Sysoev, the principal author of Nginx, said, on several occasions, that he designed the Nginx configuration language in such a way that writing the configuration should not feel like programming, or actual coding. For a long time, he himself worked as a professional system administrator for several relatively big websites in Russia. He understood perfectly that the goal of a website administrator is not to end up with beautiful, elegant configurations or to have at one's disposal every imaginable function for all possible situations no matter how rare they are. The goal is to be able to declaratively describe the business requirements, to formulate which behavior is needed without delving into how that could be achieved in software. One interesting example of quite the opposite idea in language design is the Lighttpd configuration language, but that's out of the scope of this book.

This is what we have now—a simple declarative language inspired by Apache's one but without all the XML-like tags. Open the default nginx.conf file to see what Nginx configuration looks like. Some distributions contain their own modifications to the default file. We will use the one from the original tarball available at What follows is a quick syntax introduction using parts of that file as examples. You might find it too obvious but bear with us; even the most experienced reader will do good to refresh his or her memory.

Let us look at the very beginning of the file. Lines starting with # are comments, and they are ignored. Commenting out is a very common technique to make Nginx ignore a part of configuration. The topmost line in default Nginx configuration file (as of version 1.9.12) is actually commented out:

#user  nobody;

One easy way to comment out a block of lines in vim is highlighting them visually with Shift-V and then issuing the :s/^/#/ ex command. In Emacs, just select a region and then press M-;.

Nonempty noncommented lines in Nginx configuration are of the two following types.

Simple directives

Simple directives consist of a command word followed by a number of parameters and a semicolon. For example (see at the top of the default nginx.conf file):

worker_processes  1;

Nothing to worry about here. People having too much experience with modern scripting languages, such as Python and Ruby, tend to forget the semicolon; we advise you to make sure that you add it.

The parameters mentioned here can be either constant values (numbers or strings, which does not matter, they are all parsed in the same way at this level) or they may contain variables. Variables in Nginx are the $dollar_prefixed identifiers that are replaced with some actual value at runtime. For example, there are variables containing data from an HTTP request, and you can modify website behavior depending on their values or just log them.

A very good example of variables in the default nginx.conf file is this:

#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
#                  '$status $body_bytes_sent "$http_referer" '
#                  '"$http_user_agent" "$http_x_forwarded_for"';

This directive creates a log format by constructing a template for each line of the log. It uses a number of variables available during the request/response cycle.

Multiline directives

Multiline directives are simple directives with a BUT. Instead of a semicolon in the end, there is a block enclosed in braces { ... }. And here instead is meant literally. You don't put semicolons after closing braces. Those of you with just enough experience with more traditional C-like syntax programming languages will find this very natural.

Here is an example of the very first multiline directive in the default Nginx 1.9.12 nginx.conf file:

events {
    worker_connections  1024;

Now, this is an events directive, which does not have any parameters, and it contains a block instead of a semicolon. Because of these blocks, multiline directives are also named "block directives". Blocks contain various kinds of content, but one of the most important and interesting blocks is the one containing other directives—both simple and multiline.

In the previous example, the block of the events directive contains a simple worker_connections directive.

Multiline directives that allow other directives inside their blocks are named "contexts". They introduce new context for the enclosed, inner part of the configuration.

Most of the multiline directives are actually contexts—from the most popular, such as server or location, to the most obscure, such as limit_except. An example of a multiline directive that is not a context is types, which introduces the relation between file extensions and the so-called Multipurpose Internet Mail Extensions (MIME) types. We will look at types later in this chapter.

Contexts are very important. They are scopes and topics of the directives that are inside. If a command is not included in any multiline directive block, then it is considered part of the special context named "main" with the widest scope. Directives in this context affect the whole Nginx application. Other contexts are all either inside "main" or even deeper below, and the commands that are contained within those contexts have narrower scopes and affect only parts of the whole.

Include directive

We will not describe actual directives here except for one of them. It is the include directive, a special dear to the hearts of all sysadmins who scale their work to many websites, servers, or just URLs. It is a very simple block-level "package management tool" if we are allowed to use more programming terminology. This simple directive has one parameter, that is, a filename or a wild card (UNIX glob-style) matching a number of files. During processing, this directive is replaced by the contents of the files it refers to. A quick example (from the default nginx.conf file):

include fastcgi_params;

We won't offend you by spending more time on explaining include. What we need to add is that included files have to be fully correct syntactically. You cannot have half of a command in one file and then include the rest from another.

So, this is it, the whole syntax is described. Let us show you a fictional piece of configuration that demonstrates everything but does not actually work because it contains nonexistent directives (or maybe those are from some future version of Nginx):

simple_command 4 "two";
# another_simple_command 0;

special_context {
    some_special_command /new/path;
    multiline_directive param {
        1 2 3 5 8 13;
    include common_parameters;