I have a django app and I want to to setup Varnish on a server in front of it. In another serverfault thread somebody suggested putting Nginx in front of Varnish.
Should I put Nginx in front of Varnish on the caching server? If so, should I use Nginx on the app server?
We are talking 1 - 3 frontend servers in total, not a large server farm with load balancing between the tiers?
Putting nginx in front of Vanish enables you to do HTTP compression on the fly. That is a performance best practice, but it could be dispensed with. (Content in Varnish is often kept uncompressed, so that ESI Includes work, and so you don't have to deal with multiple cached versions of the same object depending on Vary header / browser matching.)
Regarding nginx on the app server -- is Apache with mod_wsgi not the recommended and most common way to deploy new Django installations nowadays? I'm not aware of a compelling reason for using nginx/fastcgi over Apache/mod_wsgi for Django; but you should get advice from a Django expert.
Regarding Varnish having attractive load balancing features that nginx doesn't have, I don't see what they are? Varnish has random and round-robin balancing. nginx has round-robin, client IP and consistent hashing -- I don't see a significant benefit for Varnish? Is it VCL or Varnish' graceful config reload or something else?
For a small 1-3 server setup I guess I would just do
or maybe
and ignore HTTP compression for simplicity, unless bandwith is expensive.
Update:
Graham Dumpleton has written a valuable comment below. He mentions a very common setup for for example a blog on a VPS, or a small web farm without caching:
This is a very good solution, for a couple of reasons:
The reason I didn't mention this initially is that OP seemed to require Varnish, a very high performance caching solution. The nginx / Apache / mod_wsgi combo can not do caching with a level of performance and flexibility that matches Varnish.
You can use nginx without varnish to proxy and cache the content.
I've being using Nginx, Varnish, and Apache/mod_wsgi/Django successfully. I started with the following config:
Once I started seeing significant load on Apache, I added Varnish:
I use Nginx as a kind of "URL router". Django admin requests are sent directly from Nginx to Apache. Client requests are sent from Nginx to Varnish which caches the requests from Apache and also serves "graced" items from the cache if the app servers are unavailable.
My Nginx server also serves certain static content directly (e.g. images, CSS, and javascript files).
In general, performance has been excellent. I have noticed a couple of caveats that I should mention:
I'm using Nginx->Varnish->uWSGI->Django