Starting a Django Project the Right Way
jeffknupp.com
jeffknupp.com
$ git add .
Wait, what? No!This will add the whole venv, which contains symlinks, scripts with shebangs, and potential binaries, and as such is totally linked to your system, so this definitely breaks if your python ends up in another location or you're entirely on another OS.
What should be done is
virtualenv env --no-site-packages
echo "/env" >> .gitignore
pip freeze > requirements.txt
So when you want to restore/deploy you'd do git clone foo
cd foo
virtualenv env --no-site-packages
source ./env/bin/activate
pip install -r requirements.txt
I'm not even considering the issues regarding the presented git workflow. If one wants to semi-automate a git workflow, one would rather use git-flow instead of this prepare_deployment hack. [hooks]
pretxncommit.pip = bash -c "diff -u requirements.txt <(source env/bin/activate && pip freeze)"I've been using virtualenvwrapper since the separate virtualenv dir feature was added (and before), though. Seriously - just use virtualenvwrapper.
Using virtualenv in production mostly boils down to `pip -r reqs.txt -E virtual_env`(in place of pip install -r reqs.txt) and making sure virtualenv path is the first in sys.path http://code.google.com/p/modwsgi/wiki/VirtualEnvironments
You can also execfile the activation script, but I prefer changing sys.path.
It gives you flexibility on your environment and lets you deploy onto machines without a C compiler, or strange setup requirements e.g. psycopg2 on OS X, and PIL on Ubuntu.
You then install Django, and other Python-only dependencies inside your virtualenv, which stops you polluting the global Python path.
It requires some discipline in your development setup, but it means you're able to develop across whatever platform you choose, and simplifies deployment.
a) Another step to remember b) Requires a compiler on the production system c) Requires you to manually resolve the image library dependencies
Multiplying that across multiple packages can quicky become a headache. It's much easier to let the OS package manager deal with this, and will make your system more robust over time.
It's easier to set up than puppet/chef, but you lose a huge amount of flexibility/robustness. All fabric does is runs commands on host machines. Dependency management is your responsibility.
The issue I ran into with fabric is that I often got stuck in dependency hell. The following is fabric's simplest method of dependency management:
def install_foo():
install_foo_dependency()
...
Unfortunately, you don't want to do this every time you deploy because install_foo_dependency() might take a while to run. You can work around it by checking inside install_foo_dependency whether it's already there. In practice, you probably won't always do this. Puppet usually has recipes which already do this for you.So you typically have functions like:
def full_deploy():
install_foo_dependency()
install_foo_without_dependency()
In theory, you can do things right with fabric. In practice, you have to do a lot of work to replicate what puppet (together with assorted easy to find recipes) gives you out of the box.Why not use pip(pip install -r reqs.txt)?
def install_deps():
local('pip install -r reqs.txt')
Or if you are talking system dependencies, use apt-get or yum or whatever comes with your system from within fabric. with in_tmp_dir():
run('wget http://someserver/project_bleeding_edge.tar.gz')
run('tar -xvzf project_bleeding_edge.tar.gz')
run('./configure; make;')
sudo('make install')
put('conf/server.conf', 'server.conf')
sudo('mv server.conf /etc/server.conf')
(I forget if in_tmp_dir is builtin, but if not it does exactly what it sounds like.)edit: Doh, I can't read
Anyway, you can go a long way with just a bunch of scripts leveraging Fabric's API. I have setup ~10 servers for a news portal I run from the ground up in just a few lines of code. Managing dependencies is not ridiculously difficult as you make it sound, package managers (apt-get, pip) already handle that for you without any overhead.
[1] for a yet to be determined value of soon
if you do a lot of django development, you probably already got a kick ass project template with a requirements file, so you have a basic working website with all the commonly used modules set up and running in 5 seconds.
I've coded in CakePHP, Rails and ASP.Net MVC3, and out of all three MVC3 was the cleanest one for me just because any Model you created was just a simple POCO class. It didn't map anywhere and prevented you from shooting yourself in the proverbial foot. Problems inherent in Rails and CakePHP if you aren't careful.
I even asked a question on SO about this issue, ZERO responses if you can believe that. I guess the silence is answer enough. ;)
http://stackoverflow.com/questions/11424719/where-do-viewmod...