Debugging Nginx Configuration

By default, Nginx logs only standard errors to default Nginx error log file or a file specified by error_log directive in site-specific server configuration.

We can control many aspects about error logging which will help us debug our Nginx configuration.

Important: After any change to any Nginx configuration file, you must test and reload Nginx configuration for changes to take effect. On Ubuntu, you can simply run nginx -t && service nginx reload command.

Before we proceed…

I believe, we never break something that we never code! So before you copy-paste any Nginx config, make sure you remove unwanted codes. Also, every time you upgrade Nginx, update your config files also to use latest Nginx offering.

And before we proceed, please read these official articles: common Nginx Pitfallsif-is-evillocation-directive & Nginx’s request processing. You might end up fixing your problem using them alone.

Alright… looks like you need some serious debugging… Lets go ahead!

Debug only rewrite rules

Most of the time, you will be needing this only. Specially when you are seeing 404 or unexpected pages.

server {
        #other config
        error_log    /var/logs/nginx/example.com.error.log;
        rewrite_log on;
        #other config
}

rewrite_log is simply a flag. When turned on, it will send rewrite related log messages insideerror_log file with [notice] level.

So once you turn it on, start looking for log messages in error_log file.

Set Nginx log-level to debug

Following example adds debug log-level which logs most to specified path:

server {
        #other config
        error_log    /var/logs/nginx/example.com.error.log debug;
        #other config
}

debug will log maximum messages. You can find other possible values here.

Note: Do NOT forget to revert debug-level for error_log on a *very* high traffic site. error_log may end up eating all your available disk space and cause your server to crash!

Set Nginx to log errors from your IP only

When you will set log-level to debugyour error log will log so many messages for every request that it will become meaningless if you are debugging a high-traffic site on a live-server.

To force Nginx to log errors from only your IP, add the following line to events{..} block inside /etc/nginx/nginx.conf

Make sure you replace 1.2.3.4 with your own public IP. You can find your public IP here.

events {
        debug_connection 1.2.3.4;
}

You can find more details on this here.

Nginx Location Specific Error logs

In Nginx, we use location{..} block all over.

To debug parts of an application, you can specify error_log directive inside one or more location{..} block.

server {
        #other config
        error_log    /var/logs/nginx/example.com.error.log;
        location /admin/ { 
        error_log /var/logs/nginx/admin-error.log debug; 
    }         
    #other config
}

Above will debug only /admin/ part of you application and error logs will be recorded to a different file.

You can combine location-specific error_log with debug_connection to gain more control over debug logs.

Debug using Nginx’s HttpEchoModule

HttpEchoModule is a separate Nginx module which can help you debug in altogether different way. This module doesn’t come bundled with Nginx.

You need to recompile Nginx to use this. For Ubuntu users, there is a launchpad repo.

I recently came across this and I am yet to use it for debugging on a project. When I will do it, I will post details about it.

Using Perl/Lua Language for Nginx config

If you are still having a tough time and you config Nginx regularly, should consider using other languages for Nginx configuration.

There is a Nginx module for Perl language and one for Lua language.

As I am very bad at learning new languages, chances are less that I will ever write more on this. But it might be fun if you already know or can easily learn Perl/Lua.

More…