Difference between revisions of "Nginx"

From WhyAskWhy.org Wiki
Jump to: navigation, search
m (Added changelog links)
m (Added a link to "Understanding the Nginx Configuration Inheritance Model" (need to re-read it))
 
(19 intermediate revisions by the same user not shown)
Line 6: Line 6:
 
{{WorkInProgress}}
 
{{WorkInProgress}}
  
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 of the <code>location</code> blocks.
+
== Subpages ==
  
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.
+
{{Special:PrefixIndex/Nginx/}}
  
== Location blocks ==
 
  
According to the official documentation <ref>[http://nginx.org/en/docs/http/request_processing.html#simple_php_site_configuration How nginx processes a request, A simple PHP configuration]</ref>, this is how nginx processes a request:
+
== 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.
 +
 
 +
{{InfoBox|warning|Pay close attention to what version of nginx a book or web resource is based on as behavior may change between releases <ref name="prefix-none" />}}
 +
 
 +
 
 +
=== Directives ===
 +
 
 +
==== Case-sensitive ====
 +
 
 +
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 <ref name="apache-directives" />, but with nginx, directives are case-sensitive.
 +
 
 +
 
 +
==== Array values ====
 +
 
 +
Another gotcha is setting array values <ref name="nginx-array-values" />. It may not be immediately obvious, but when using a directive like <code>access_log</code> 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:
 +
 
 +
<syntaxhighlight lang="nginx">
 +
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
 +
        # Note: See explanation below about the first access_log that was defined
 +
        access_log  /var/log/nginx/www.access.log vhost_combined_debugging;
 +
 
 +
        # more conf statements here
 +
    }
 +
 
 +
}
 +
</syntaxhighlight>
 +
 
 +
Defining that second <code>access_log</code> value resets the array and causes the earlier array values (other access logs) 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:
  
 
<blockquote>
 
<blockquote>
nginx first searches for the most specific prefix location given by literal strings regardless of the listed order. In the configuration above the only prefix location is “/” and since it matches any request it will be used as a last resort. Then nginx checks locations given by regular expression in the order listed in the configuration file. The first matching expression stops the search and nginx will use this location. If no regular expression matches a request, then nginx uses the most specific prefix location found earlier.
+
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.).
 
</blockquote>
 
</blockquote>
  
The same thing, said a little differently according to Samuel at the [http://blog.rackcorp.com/?p=31 RackCorp Industry Blog]:
 
  
<blockquote>
+
==== Location blocks ====
The best way to think of things is that as a request comes in, Nginx will scan through the configuration to find a "location" line that matches the request. There are TWO modes that nginx uses to scan through the configuration file: '''literal string matching''' and '''regular expression checks'''. Nginx first scans through ALL literal string location entries in the order that they occur in the configuration file, and secondly scans through ALL the regular expression location entries in the order that they occur in the configuration file. So be aware – ''location ordering order DOES matter''.
 
</blockquote>
 
  
 +
This one directive to me is the biggest difference between how Apache and nginx processes requests. The <code>location</code> blocks gave me a lot of trouble until I went through the nginx documentation and wiki pages. I also made the mistake of placing everything in include files which often muddied the picture for me. If you're new to nginx and are having trouble getting certain <code>location</code> blocks to match, I recommend ''not'' placing the <code>location</code> blocks in include files until you are comfortable with how nginx handles requests. See [[Nginx/Location]] for more information.
  
=== References ===
 
  
<references />
 
  
 
=== Additional Info ===
 
=== Additional Info ===
  
* [http://library.linode.com/web-servers/nginx/configuration/basic#sph_location-configuration Linode Library, Basic Nginx Configuration, Location Configuration]
+
* [http://kbeezie.com/view/securing-nginx-php/2/ Securing nginx and PHP]
* [http://wiki.nginx.org/HttpCoreModule#location nginx wiki - HttpCoreModule]
 
* [http://stackoverflow.com/questions/8437613/nginx-location-directive-matching-order stackoverflow - location directive matching order]
 
 
* [http://www.ruby-forum.com/topic/151853 History of nginx]
 
* [http://www.ruby-forum.com/topic/151853 History of nginx]
 +
* [http://articles.slicehost.com/2010/8/27/customizing-nginx-web-logs Customizing nginx web logs]
 +
* [http://blog.martinfjordvald.com/2012/08/understanding-the-nginx-configuration-inheritance-model/ Understanding the Nginx Configuration Inheritance Model]
 +
 +
 +
==== References ====
 +
 +
<references>
 +
<ref name="prefix-none">[http://nginx.org/en/docs/http/ngx_http_core_module.html#location In versions from 0.7.1 to 0.8.41, if a request matched the prefix location without the "=" and "^~" prefixes, the search also terminated and regular expressions were not checked.]</ref>
 +
<ref name="apache-directives">[http://httpd.apache.org/docs/2.2/configuring.html Apache 2.2.x Configuration Files]</ref>
 +
<ref name="nginx-array-values">[http://permalink.gmane.org/gmane.comp.web.nginx.english/4022 possible fastcgi_params bug or undocumented feature]</ref>
 +
</references>
  
  
Line 40: Line 98:
  
 
* [http://www.nginx.org/en/CHANGES All releases, including development releases]
 
* [http://www.nginx.org/en/CHANGES All releases, including development releases]
* [http://www.nginx.org/en/CHANGES 1.2.x series]
+
* [http://nginx.org/en/CHANGES-1.2 1.2.x series]
  
  
 
==== Books ====
 
==== Books ====
  
* [http://www.packtpub.com/nginx-http-server-for-web-applications/book PacktPub - Nginx HTTP Server]
+
Unfortunately there are not a lot of books on nginx out there, and the ones that are available are starting to show their age.
 +
 
 +
===== Nginx HTTP Server =====
 +
 
 +
The one I got started with is [http://www.packtpub.com/nginx-http-server-for-web-applications/book Nginx HTTP Server] and while it doesn't cover the current nginx versions available it is good place to start. Just make sure to check any suggestions it offers against current nginx documentation and wiki pages before putting the configurations into production.
 +
 
 
{| class="wikitable sortable" style="text-align: center;"
 
{| class="wikitable sortable" style="text-align: center;"
 
|+nginx versions covered (Jun 2010)
 
|+nginx versions covered (Jun 2010)

Latest revision as of 09:26, 6 September 2012




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.


Subpages


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.


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


Directives

Case-sensitive

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 [2], but with nginx, directives are case-sensitive.


Array values

Another gotcha is setting array values [3]. 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
        # Note: See explanation below about the first access_log that was defined
        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 (other access logs) 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.).


Location blocks

This one directive to me is the biggest difference between how Apache and nginx processes requests. The location blocks gave me a lot of trouble until I went through the nginx documentation and wiki pages. I also made the mistake of placing everything in include files which often muddied the picture for me. If you're new to nginx and are having trouble getting certain location blocks to match, I recommend not placing the location blocks in include files until you are comfortable with how nginx handles requests. See Nginx/Location for more information.


Additional Info


References


Changelogs


Books

Unfortunately there are not a lot of books on nginx out there, and the ones that are available are starting to show their age.

Nginx HTTP Server

The one I got started with is Nginx HTTP Server and while it doesn't cover the current nginx versions available it is good place to start. Just make sure to check any suggestions it offers against current nginx documentation and wiki pages before putting the configurations into production.

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