Virtualenv is a project that is indispensable for most Python devs these days. I am writing down some tips here so mainly for personal reference, and because I found them useful.
Virtualenv & Upstart¶
For my ReadTheDocs project, I was wanting to run celery as a background process that processes documentation building. I’m running Ubuntu, so their built-in upstart service seems like a logical choice. I really like upstart because of it’s simple configuration, but it is rather undocumented (this Stanzas) page is a useful starting point).
Carl Meyer pointed out to me that
to get inside the context of a virtualenv, you don’t need to munge your pythonpath or anything, but simply run the correct script from inside the virtualenv.
So a simple
/path/to/virtualenv/bin/django-admin.py celeryd was
all that was needed to get inside the virtualenv’s context.
This also true of the python executable inside your python
/path/to/virtualenv/bin/python will allow you to run
any python script inside of that virtualenv’s context.
I also wanted to be running my jobs as the user for that site, so
sudo is the correct tool for that. The final file ended up
looking like this:
description "Celery for ReadTheDocs" start on runlevel  stop on runlevel [!2345] #Send KILL after 20 seconds kill timeout 20 script exec sudo -i -u docs django-admin.py celeryd -f /home/docs/sites/readthedocs.com/run/celery.log -c 2 -B end script respawn
The only other interesting bit there is the
-i option to sudo,
which means it will run the command as a login shell, picking up
the environment for the user. This means it has the correct path
and everything set, so that
django-admin.py works without an
Adding site-packages in after initial creation¶
Frank Wiles ran into this problem
on IRC, where he wanted to add in the site-packages after creating
a virtualenv with
--no-site-packages. It turns out to be really
simple, in that you only have to remove the
no-global-site-packages.txt in the
inside the virtualenv. After that virtualenv will go ahead and
fallback to the global site packages happily.
I’d imagine this would work the other way as well, if you want to not have your site-packages included, you could add this file into your virtualenv.
is a nice set of extensions around virtualenv. It gives you handy
command line helpers, like
workon which autocompletes the names
of your virtualenv’s. It has its own
Tips and Tricks
page that has some neat ideas about how to improve your virtualenv
Deploying with virtualenv and apache has been well covered. I recommend this Caktus post that gives some good examples.
The main idea however, is that you make sure your the virtualenv’s pythonpath is on your pythonpath, or that you are running the virtualenv’s python when you run your webserver. For apache, in your wsgi file, you generally do something like:
site_packages = os.path.join(PROJECT_ROOT, 'env/lib/python2.6/site-packages') site.addsitedir(os.path.abspath(site_packages))
For a gunicorn deployment, you would do something along the lines
/path/to/virtualenv/bin/python manage.py run_gunicorn.
I’d love to hear your tips about how to use virtualenv in the best way possible. I know that my workflow is probably lacking, and these aren’t all or even many of the neat things you can do with virtualenv.