For a small django site I run, I'd like to add nginx caching in front of my django server. Here's the setup I ended up with.
The pages I want to cache are available for both anonymous and logged in users. The majority of traffic is from anonymous users and since they all get the same contents I'd like to serve it from the cache. Contents for logged in users should never be cached.
Because we show different content to logged in users, and therefore check e.g.
SessionMiddleware correctly sets a
Vary: cookie header.
As an extra spanner in the works, we use google analytics which adds its own cookies. These aren't used by the django server but means that even anonymous visitors submit cookies with their request.
By default, nginx respects the
vary header and adds the cookies to the cache key, effectively giving everyone their own cache entry which is useless.
The fix is to ignore the
Vary header, and instead bypass the cache for anyone with a
The nginx blog had a nice guide on how to configure caching where i got most of the settings from, though it unhelpfully doesn't mention the need for a
Final nginx config:
proxy_cache_path /tmp/nginx-cache levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
proxy_cache_valid 200 10m;
# ignore "Vary: cookie" from django and instead use
# cache_bypass for the sessionid cookie
# add a custom header with cache status, for debugging
add_header X-Cache-Status $upstream_cache_status;
$ curl -s -i -b _utm=foo https://site | head
HTTP/1.1 200 OK
$ curl -s -i -b sessionid=bar https://site | head
HTTP/1.1 200 OK