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 theproxy_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 version1.7.7
only. Using a previous nginx version withproxy_ignore_headers Set-Cookie;
would result in massive cookie duplication as theSet-Cookie
header from the cached reply would be sent back to all requests hitting the cache entry.