As I'm doing Django project deployments on a frequent basis, I've taken the
time to look into using Fabric and Pip to automate the process. With a bit of
experimenting I believe I've come up with a nice clean way to do this. My
fabric deployment script allows me to deploy a project to a new server and
because I use virtualenv to keep things segregated from each other and the base
Python system I'm free to use Pip to install anything that the project should
require.
So here's how I do it.
On my local machine I first installed Pip and Fabric.
$ sudo easy_install pip
$ sudo pip install fabric
On the server I had to install Pip and virtualenv.
$ sudo easy_install pip
$ sudo pip install virtualenv
Assume that goes to plan, the next step is to create a deployment script
(fabfile.py). Here is my fabfile.py which is hopefully commented well enough so
you can see what it's doing. It should make more sense after reading the rest
of this post.
Fabric is very simple to operate. Basically you pass the functions you want to
call into the "fab" command line script.
For example the following command will execute the "staging()" then "deploy()"
functions.
$ fab staging deploy
The "staging()" function in my script sets up some initial settings such as the
server to deploy to (config.fab_hosts) and the name of the Django settings
file. But substituing this for "production" I can easily send the deployment to
my live server.
When my site is first deployed on the new server which currently only has Pip
and virtualenv installed on it I will need to create the virtual environment
and install all the required packages using Pip.
Pip knows what to install because I pass a "requirements" file to it. This is a
simple plain text file which lists the packages to install. I store this in the
root of my project and name it "requirements.txt". Here's an example of what I
use:
Django==1.0.2-final
MySQL-python>=1.2.2
PIL==1.1.6
simplejson>=2.0.9
python-memcached>=1.44
To setup my project on the new server using my fabfile is quite simple. All I
need to do is execute:
$ fab staging setup
This calls the "setup()" function which does the following:
- Creates the initial directory to deploy to
- Creates a new virtual environment
- Clones the git repository which contains the project
- Creates some initial directories
- Copies the latest code checkout into a unique timestamped directory
- Calls Pip to install everything needed as specified in my projects requirements.txt file.
Once that has run its course the server is ready to deploy to using the
command:
$ fab staging deploy
With my fabfile this will do the following:
- Pull the latest changes into the server's copy of the git repository
- Copy the latest code into a unique timestamped directory under the "releases" directory
- Symlink the new release directory to the name "current"
- Symlink the "uploads" directory to a shared directory outside of the main project
- Run syncdb and migrations
- Restart lighttpd
Some of this stuff may be only essential to my projects, but I hope it gives
you and idea of how Fabric works and once you get it going it saves a lot of
time and effort.