Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
The perfect Django setup. (stochastictechnologies.com)
61 points by stavros on Oct 24, 2010 | hide | past | favorite | 20 comments


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) pip creates the virtualenv if it doesn't exist, and uses --no-site-packages by default (as far as I know, anyway).

2) Why not? Varnish is awesome. Is nginx as flexible as Varnish when it comes to caching?


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 :)


Well, if your setup (Varnish+Apache) works for you then there is no need to change it (unless you really need to).

However, recommending this (Varnish+nginx) just leads to more people repeating the same mistake.


Varnish can also act as a (pretty good) load-balancer for your HTTP servers.


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... ;)).


Do you need to modify your manage.py?

  source /usr/bin/local/virtualenvwrapper.sh
  workon yoursitevirtualenv
  ./manage.py migrate
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.


You don't, if you need to change envs for a single project. Otherwise, there's no reason why you need to type two(/three) commands when one will do...


Something for your fabfile (for pushing to production and migrating):

  def with_virtualenv(command):
      "Executes a command in this project's virtual environment."
      run('source /usr/local/bin/virtualenvwrapper.sh && workon %s && %s' % (env.virtualenvname, command), pty=True)
e.g. usage: with_virtualenv('python manage.py migrate')

For your local development, throw the virtualenv wrapper initialization into your bashrc (Only need to do this once.)

  echo "source /usr/bin/local/virtualenvwrapper.sh" >> ~/.bashrc
When you're developing, always start by activating your virtual environment.


Why would I need to do that? I can just change the shebang line in manage.py and never ever need to activate the virtualenv...


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.

I could be wrong.


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?"

:)


Thank you, I'm glad you found it useful!


Please let me know if we've forgotten something, we'd love to add some more info.


So are you versioning the env/ directory (which as I understand it is located under your project folder), or just dependencies.txt?


No, I should clarify. The env dir is not versioned, since its entire state should be in dependencies.txt. Thank you for that observation.


These articles always seem to leave out the biggest question: "how can I reload my code without having root access and restarting the web server".


If you use mod_wsgi, you can just touch the .wsgi file. I think uwsgi supports reloading when the code files change, too.


I think the mod_wsgi thing might only work in daemon mode.

If you're in sufficiently dire straits, remember that switching to Linode and becoming root yourself is always an option.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: