Where should virtualenvs be created?

Many people use the virtualenvwrapper tool, which keeps all virtualenvs in the same place (the ~/.virtualenvs directory) and allows shortcuts for creating and keeping them there. For example, you might do:

mkvirtualenv djangoproject

and then later:

workon djangoproject

It's probably a bad idea to keep the virtualenv directory in the project itself, since you don't want to distribute it (it might be specific to your computer or operating system). Instead, keep a requirements.txt file using pip:

pip freeze > requirements.txt

and distribute that. This will allow others using your project to reinstall all the same requirements into their virtualenv with:

pip install -r requirements.txt

The generally accepted place to put them is the same place that the default installation of virtualenvwrapper puts them: ~/.virtualenvs

Related: virtualenvwrapper is an excellent tool that provides shorthands for the common virtualenv commands. http://www.doughellmann.com/projects/virtualenvwrapper/


Changing the location of the virtualenv directory breaks it

This is one advantage of putting the directory outside of the repository tree, e.g. under ~/.virtualenvs with virutalenvwrapper.

Otherwise, if you keep it in the project tree, moving the project location will break the virtualenv.

See: Renaming a virtualenv folder without breaking it

There is --relocatable but it is known to not be perfect.

Another minor advantage: you don't have to .gitignore it.

The advantages of putting it gitignored in the project tree itself are:

  • keeps related stuff close together.
  • you will likely never reuse a given virtualenv across projects, so putting it somewhere else does not give much advantage

This is an annoying design flaw in my opinion. They should implement virutalenv in a way that does not matter where the directory is, as storing in-tree is just simpler and more isolated. Node.js' NPM package manager does it without any problem. And while we are at it: pip should just use local directories by default just like NPM. Having this separate virtualenv layer is wonky. Node.js just have NPM that does it all without extra typing. I can't believe I'm prasing the JavaScript ecosystem on a Python post, but it's true.