Nginx – Configuring reverse proxy + caching

Published on Author gryzli

Here are some useful steps, how to configure nginx reverse proxy + caching. 

 

 

1) How does Nginx  proxy cache works ? 

 

How does Nginx reverse proxy cache works
Nginx Proxy Caching

 

 

In the scheme above we are considering that we have Apache upstream/origin server and in front of it Nginx which does reverse proxying + caching of Apache response. 

 

Basically what happens is as follows

1 ) Client request comes to Nginx, asking for some resource

2 ) Nginx checks if it has the resource already in its cache 

3 ) If the resource is cached, Nginx returns the cached content 

4 ) If the resource is NOT cached, Nginx proxies the request to backend/origin server (Apache in our case)

 

 

2) How to configure Nginx proxy/caching

In order to configure proxying/caching in Nginx, we must go through several easy steps, the first of which is setting proxy_cache_path. 

 

 

2.1 ) Configure appropriate proxy_cache_path 

 

First of all we must configure proxy_cache_path, this is something like defining our ‘cache object’ which will be later referred and used to generate/store cache files. 

We are going to use the the following example proxy-cac

 

How nginx proxy_cache_path works
Nginx proxy_cache_path

 

This is our example proxy_cache_path directive (above is some explanation which setting what means.

proxy_cache_path /var/nginx_cache/gryzli.info levels=1:2 keys_zone=gryzli.info:2m max_size=256m inactive=12h use_temp_path=off;

 

This is what our proxy_cache_path says:

  • Store cache files inside /var/nginx_cache/gryzli.info
  • Use 2 level directory structure (levels=1:2)
  • Make the name of this cache object: gryzli.info
    • Use 2m in memory for cache key mappings (2m is about 2 000 cache objects)
  • Limit the size of cache directory to “max_size=256m”
  • Delete cache files if they are not used for “inactive=12h
  • Don’t use custom path for temporary cache files (use_temp_path=off)

 

 

2.2 ) Configure good proxy_cache_key

It is very important to change the default proxy_cache_key !

By default proxy_cache_key is this:

$scheme$proxy_host$request_uri;

The problem here is that there is no “$host” in the default key.

This means, that if you have Redirect 301 from domain.com to www.domain.com, and you have the chance to first hit non-www domain, you will always receive 301 redirect from Nginx caching, causing redirect loop.

In order to fix this misbehavior, you need to add at least the following proxy_cache_key:

proxy_cache_key $scheme$host$proxy_host$request_uri;

Now as the $host is part of the key, the problem with non-www to www redirect loop is solved !

 

2.3 ) Configuring proxy_cache_valid

Another very important option is “proxy_cache_valid”, which tells Nginx, what would be the maximum period given cached resource, should be valid. If you have cached page for more than cache_valid time, it will be expired and re-freshed.

 

2.4 ) Configuring some important headers

This is my example configuration for headers:

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;

Here the most important one is : “ proxy_set_header Host $host” .

By setting the Host header, we are telling upstream/backend server (in our case Apache), which exact vhost it should access to return the content.

 

2.5 ) Finally configuring the timeouts

Our final step is to configure some good timeouts, cause the default ones are very low. Here is what I use:

        # Set some good timeouts
        proxy_connect_timeout       300;
        proxy_send_timeout          300;
        proxy_read_timeout          300;
        send_timeout                300;

This sets all timeouts to 5 minutes (most of them are default to 1 minute).

 

 

3 ) Get everything glued together Proxy + Caching

This is how my config looks like:

    location / {
        proxy_cache gryzli.info ;
        proxy_cache_key $scheme$host$proxy_host$request_uri;

        proxy_cache_valid 15m; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_revalidate on; 

        # Set some good timeouts 
        proxy_connect_timeout       300;
        proxy_send_timeout          300;
        proxy_read_timeout          300;
        send_timeout                300;


        # 1.1.1.1 is my internal backend IP 
        proxy_pass https://1.1.1.1:443 ; 
    }

 

 

4) Resource you should read !

If you ever think of setting Nginx caching for reverse proxied request, I recommend reading the following resources (which helped a lot to me)

Nginx caching based on page size

Checking your nginx caching status

Basic content caching

Guid to caching

some more advanced tips:

High Performance Caching