

The perfect Django setup. - StavrosK
http://blog.stochastictechnologies.com/the-perfect-django-setup

======
piotrSikora
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...

~~~
StavrosK
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?

~~~
piotrSikora
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 ;)

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

~~~
piotrSikora
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.

------
Nagyman
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.

~~~
StavrosK
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...

~~~
Nagyman
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.

~~~
StavrosK
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...

~~~
Nagyman
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.

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

:)

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

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

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

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

------
gnuvince
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".

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

~~~
astrofinch
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.

