Nice article, although I would like to point 2 things:
1) The line for creating virtualenv is really missing. Also, you would probably like to point out that it should be create with "--no-site-packages" (at least that's the way I prefer to do it).
2) Why there is Varnish in front of nginx? I see this mistake repeated again and again...
1) Sorry, my bad... Usually I've got only setuptools and virtualenv globally installed, so pip is not available outside of virtualenv.
2) I know that Varnish is awesome, don't get me wrong. But for the most use cases putting Varnish in front of nginx doesn't add any benefits... nginx on its own can handle pretty much all standard caching use cases, so Varnish is adding only a little of per-request overhead. Of course YMMV ;)
I agree, varnish in front of nginx might be a bit overkill. We use varnish because we run apache, and I'm so infatuated with it that I recommend it to everyone. I've seen it pull off thousands of requests a second without breaking a sweat, then again nginx is no sloth either.
We are considering switching from apache, but the current setup works so well that we don't want to mess with it :)
So can nginx... And it's probably a lot better at it because of number of 3rd-party load balancers and supported backend protocols (HTTP, FastCGI, SCGI, uwsgi, AJP, PostgreSQL, Drizzle, MySQL, memcached, redis and then some more... ;)).
Virtualenv changes the current environment variables to use the correct python version. So the shebang in manage.py (/usr/bin/env python) will use the right version and installed packages.
The upside is you can change your python version & packages without changing hard coded paths to the virtual environment you want to use.
One of the big benefits of using virtualenv is that you can change the environment your code is running within. For example, if I want to test a new version of a package (or a new version of python altogether), I can create another virtual environment and "workon [newenvname]", ./manage.py runserver..., and test away.
It also follows the principal of least surprise. As a developer, if I run a python file, I generally expect it to use the python version in my environment, not some hard coded path. This is exactly why manage.py references python in the environment (/usr/bin/_env_) and not a direct path to the python executable.
It's easy to switch virtual environments and unexpected that I'd have to change code.
Thank you for posting these. I just started a small project with Django this weekend, and this neatly answers a few of my niggling questions (like "how should I actually migrate data if syncdb doesn't modify tables?" and "how do I manage virtualenvs in deployment?"
1) The line for creating virtualenv is really missing. Also, you would probably like to point out that it should be create with "--no-site-packages" (at least that's the way I prefer to do it).
2) Why there is Varnish in front of nginx? I see this mistake repeated again and again...