Home > Server stuff > A few notes about nginx

A few notes about nginx

Nginx is a great, fast HTTP server but I often stumbled upon some problems when configuring it. Mainly because the fact that official documentation is not concrete and clear enough.

That’s why I decided to write down some notes and experience I gained during nginx usage. Some of comments mentioned here may become obsolete or may not be true completely, but this is what I used and what worked for me.

Hiding nginx version

It’s a good idea to disable sending the nginx version in headers and error pages. This may prevent an attacker from trying existing exploits for a particular server version. You can do that by adding this line to the “server” block:

server_tokens off; # disable sending nginx version in Server and error pages


While the official documentation has Debugging page, it’s better to simply mention two important configuration directives. You can place these in any server {} block.

# enables logging of rewrites to see which rewrite regexp was matched for which input
rewrite_log on;
# specifies "debug" log level for specified log file 
error_log       /var/log/nginx/domain.com-error_log debug;

Using these two can help you investigate what’s going on more closely.


Index directive is bread and butter for every website but did you know that you can specify relative paths to index files if they are not in the root directory? Let’s have a look:

index wp/index.php index.html index.php default.htm;


Sometimes you may need to do a simple redirection from one domain to another. It’s simple:

server {
   include listen.inc; # include listen lines
   server_name original.com; # from which domain to redirect
   return 301 http://new.com$request_uri; # to which domain to redirect

If you need to redirect POST and other complicated requests, the only possible option seems to be a proxy module (see http://wiki.nginx.org/HttpProxyModule).


Try files is definitely a very useful thing. But you should know how it works before you try to use it, otherwise you are going to lose many hours like I did.

Documentation definitely does it’s job by defining what try_files do, but does not mention how it behaves if you have several location {} blocks and whether you should specify it in a location {} block or in a server {} block.

I had a problem when I wanted to run WordPress php scripts which resided in a subfolder of the root folder. The problem was, how to correctly specify try_files. After hours and hours of trying, I discovered, that I should use two try_files. One for server{} block to serve static files like images, the other for .php location{} block to serve scripts because it seems that location block has priority over what is specified in server block.
Look at this example:

server {
   #it seems that this will work for static files and files which are not server by any location sub-block
   try_files $uri $uri/ /wp/$uri /wp$uri /wp$uri/ /wp/index.php?q=$uri&$args;

   location ~ \.php$ {
       #it seems that this needs to be here again because the location block has the priority and try_files in the server block won't be used
       try_files $uri $uri/ /wp/$uri /wp$uri /wp$uri/ /wp/index.php?q=$uri&$args;

It should be clear from comments. But note that if you use some includes (for example for defining php or cgi handling) and include that file in a location block, make sure this include does not specify a try_files directive again.

The order of location blocks

The order of location blocks is important only for blocks using regexp. “location /” is special and is used as a last resort.
It documented quite well so I invite you to read the official documentation.

Rewrite in a location block

I wanted to set up two location blocks for two url types (subfolders) and also using try_files to find static contents when it exists. For a non-existent path I wanted the same “index.php” script to be executed so it was not possible to use “.php$” regexp. I solved it by having four locations like this:

location /no-cache {
try_files $uri $uri/ @php_nocache;

location / {
try_files $uri $uri/ @php;

location @php {
rewrite ^ /index.php; # this is the trick
include microcache.inc;
include php.loc;

location @php_nocache {
rewrite ^ /index.php;  # this is the trick
include php.loc;

The trick was to use rewrite in the final “location” block so that the same index.php script can be executed.


There were more problems I encountered but I can’t remember all of them.
But hopefully this post can help a few people with similar problems.
I will update this post when I face new problems or discover new facts.

Categories: Server stuff Tags: , , , ,
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x
deadly laser