vote up 4 vote down star
3

I heard recently that Nginx has added caching to its reverse proxy feature. I looked around but couldn't find much info about it.

I want to set up Nginx as a caching reverse proxy in front of Apache/Django: to have Nginx proxy requests for some (but not all) dynamic pages to Apache, then cache the generated pages and serve subsequent requests for those pages from cache.

Ideally I'd want to invalidate cache in 2 ways:

  1. Set an expiration date on the cached item
  2. To explicitly invalidate the cached item. E.g. if my Django backend has updated certain data, I'd want to tell Nginx to invalidate the cache of the affected pages

Is it possible to set Nginx to do that? How?

flag

9 Answers

vote up 4 vote down check

I don't think that there is a way to explicity invalidate cached items, but here is an example of how to do the rest. Update As mentioned by Piotr in another answer, there is a cache purge module that you can use.

In this configuration, items that aren't cached will be retrieved from example.net and stored. The cached versions will be served up to future clients until they are no longer valid (60 minutes).

Your Cache-Control and Expires HTTP headers will be honored, so if you want to explicitly set an expiration date, you can do that by setting the correct headers in whatever you are proxying to.

There are lots of parameters that you can tune - see the nginx Proxy module documentation for more information about all of this including details on the meaning of the different settings/parameters: http://wiki.nginx.org/NginxHttpProxyModule#proxy_cache_path

http {
  proxy_cache_path  /var/www/cache levels=1:2 keys_zone=my-cache:8m max_size=1000m inactive=600m;
  proxy_temp_path /var/www/cache/tmp; 


  server {
    location / {
      proxy_pass http://example.net;
      proxy_cache my-cache;
      proxy_cache_valid  200 302  60m;
      proxy_cache_valid  404      1m;
    }
  }
}
link|flag
vote up 3 vote down

I suggest you give Varnish a try. Varnish is specifically designed as a reverse proxy cache. It will honor all cache control headers you send from the origin server, which satisfies your first request.

For your second request, explicit invalidation. My strong recommendation is to change the name of the url of the resource you want to invalidate, either by renaming the file or using some form of query string cache buster. Varnish does have a PURGE operation that will remove the resource from Varnish's cache, but it will not give you control over any other caches between you and the user. As you've said you want to explicitly purge a resource, then standard http control headers won't help you. In that cases the most foolproof way to defeat the caching of a resource is to rename it.

link|flag
Could you explain what did you mean by "renaming the file or using some form of query string cache buster"? I'm not sure I understand why it's not a good idea to use an operation like PURGE. – Continuation Jun 24 at 15:54
+1 for varnish. It's always much better to use the right tools for the job. – Tom O'Connor Nov 17 at 11:53
vote up 2 vote down

I believe NginxHttpProxyModule is capable of caheing http requests. Look for the directives starting with:

proxy_cache

Yes, it is possible to control cache behaviour via directives like:

proxy_cache_valid
link|flag
vote up 2 vote down

For invalidating selected pages you can use "cache_purge" patch for nginx-0.8.x which does exacly what you want ;)

It's available here.

link|flag
vote up 1 vote down

Based on the fact that you can't find docs on it, I'd be a little bit wary about relying on it in production. Have you considered Varnish? It's my "nginx of reverse proxies", small, lightweight, doing one job and doing it well.

link|flag
vote up 1 vote down

There is an nginx plugin called ncache which claims to be "a web cache system base on nginx web server. faster and more efficient than squid. "

link|flag
vote up 1 vote down

If you use eTags on your application and put nginx in front of it then it will take care of the expiration for you, because if the eTag changes it will invalidate the cache.

link|flag
vote up 1 vote down

Caching is pretty new function in nginx (and not so well documented for now), but stable enough to be used in production.

link|flag
vote up 0 vote down
fastcgi_cache_path  /opt/nginx-cache  levels=2:2   keys_zone=img:50m;

    location /img/ {
        fastcgi_pass $backend;
        include fcgi_params;
        fastcgi_intercept_errors off;   
        fastcgi_cache_key $server_addr$request_uri;       
        fastcgi_cache img;
        fastcgi_cache_valid any 1m;
        fastcgi_hide_header Set-Cookie;
    }

This creates cache for /img/ location. It is in /opt/nginx-cache. Objects are cached for 1 minute.

You can write different response codes instead of any.

Now you can't invalidate cache for selected pages. Maybe in 0.8.x it will be possible.

link|flag
The original question was about using nginx in front of Apache, not in front of fastcgi application handled by nginx. – Graham Dumpleton Jul 13 at 1:52

Your Answer

Get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.