Nginx – Why is this Nginx setup not caching responses

djangogunicornnginx

I have Nginx sitting in front of gunicorn, which in turn sits in front of a django application.

The core question is "Why are my responses not being cached?" However, I'm pretty green at this, so here are my assumptions on what should happen (in case my core understanding is flawed).

Request A hits Nginx asking for, say, some json from a REST service. Nginx doesn't have this in its cache, so it passes it onto Gunicorn/Django. A response is generated, passed back through Nginx, where it is cached, and finally back out to the client.

Then!

Request B comes in asking for the same resource. Nginx has it in its cache and thus serves it directly, never hitting the django application.

Based on that assumption, and after much reading I ended up with this minimal nginx configuration in my sites-enabled:

proxy_cache_path /tmp/nginx keys_zone=one:20m inactive=60m;
proxy_cache_key "$host$request_uri";


server {
    listen 8080;
    server_name localhost;

    proxy_cache one;

    location / {
        add_header X-Proxy-Cache $upstream_cache_status;
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
        proxy_pass http://127.0.0.1:8000;
    }
}

This code is based on the docs for nginx caching, and the tutorial here.

If I test a few requests, I get this response:

curl -X GET -I http://localhost:8080

HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Wed, 06 May 2015 01:35:38 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Cookie
X-Frame-Options: SAMEORIGIN
Set-Cookie: csrftoken=b6UG5X4ZlGwVUYfHSIkq4PKBIxicpWxc; expires=Wed, 04-May-2016 01:35:38 GMT; Max-Age=31449600; Path=/
X-Proxy-Cache: MISS

Note: I think the cookie is fine since I don't include it in the cache_key directive. I could be wrong though.

Despite numerous request for the same resource, I never get a cache hit. Further, no cache files are written in the proxy_cache_path directory.

Could someone point me towards why no responses are being cached?

Thanks!

Best Answer

Trying to cache an entity which holds a Set-Cookie header is quite a bad idea. This is natively forbidden by nginx unless told with the proxy_ignore_headers directive.

This header ignored plus the Vary: Cookie header in replies would make your cache quite ineffective since a sole resource will have as many cache entries as the amount of visitors asking for it.

Also note that the Vary header is taken into account in the caching algorithm since version 1.7.7 only. Using a previous nginx version with proxy_ignore_headers Set-Cookie; would result in massive cookie duplication as the Set-Cookie header from the cached reply would be sent back to all requests hitting the cache entry.

Related Topic