Difference between revisions of "Nginx"

From WhyAskWhy.org Wiki
Jump to: navigation, search
m (Placed subpages at the top so I could quit worrying about the transclusion messing with the parser cache (bug) and also moved inline references to reference section.)
m (Added a link to "Understanding the Nginx Configuration Inheritance Model" (need to re-read it))
 
(5 intermediate revisions by the same user not shown)
Line 13: Line 13:
 
== nginx is thorny ==
 
== 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 <code>location</code> blocks.
+
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.
 
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.
  
{{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" />}}
 
  
 +
==== 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>
 +
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>
 +
 +
 +
==== Location blocks ====
 +
 +
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.
  
  
Line 26: Line 82:
 
* [http://kbeezie.com/view/securing-nginx-php/2/ Securing nginx and PHP]
 
* [http://kbeezie.com/view/securing-nginx-php/2/ Securing nginx and PHP]
 
* [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]
  
  
Line 33: Line 91:
 
<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="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="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>
 
</references>
  
Line 39: 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 08: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

  1. 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.
  2. Apache 2.2.x Configuration Files
  3. possible fastcgi_params bug or undocumented feature


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