From Wiki
Revision as of 11:42, 26 August 2012 by Deoren (talk | contribs) (Added bit about array values.)
Jump to: navigation, search

The following content is a Work In Progress and may contain broken links, incomplete directions or other errors. Once the initial work is complete this notice will be removed. Please contact me via Twitter with any questions and I'll try to help you out.


nginx is thorny

I've been using Nginx for a few years now and plan to do so for many more, but it wasn't an easy setup to get used to. In fact, I'm still getting bit by the differences between it and Apache, which I have much more experience with. The one difference that stands out the most to me is the location blocks.


For the most part, Apache directives are matched in a top down manner with later directives overwriting earlier ones if duplicated. Nginx directives on the other hand seem to operate a little differently. One such example is that with Apache, directives in the configuration files are case-insensitive [1], but with nginx, directives are case-sensitive.

Another gotcha is setting array values [2]. It may not be immediately obvious, but when using a directive like access_log you are setting an array value. Because you are able to define multiple access logs, each use of the directive adds another entry in the array.

So in a configuration like this:

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

    # Found in default nginx 1.2.2 conf file
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    log_format vhost_combined_debugging '$server_name $remote_addr - $remote_user [$time_local] '
                    '"(request = \'$request\')" $status $bytes_sent '
                    '(request_filename = \'$request_filename\') $request_uri (args = \'$args\') '
                    '"$http_referer" "$http_user_agent"';

    access_log  /var/log/nginx/access.log  main;

    # more conf statements here

    server {
        # more conf statements here

        # Enabled/disabled as needed for troubleshooting
        access_log  /var/log/nginx/www.access.log vhost_combined_debugging;

        # more conf statements here


Defining that second access_log value resets the array and causes the earlier array values to be unset. This is unfortunate as it is easy to forget when you expect the default behavior to be one of inheritance. I've personally been bitten by this and only figured it out by observation.

Maxim Dounin explains it as:

Basically, when you set array directive at certan (sic) level this clears everything inherited from upper levels for this array. This applies to other array directives as well (proxy_add_header, access_log, etc.).

Pay close attention to what version of nginx a book or web resource is based on as behavior may change between releases [3]

Additional Info




nginx versions covered (Jun 2010)
Stable Dev Legacy
0.7.66 0.8.40 0.5.38, 0.6.39