Django & Capistrano
One of the major Django‘s drawback for a project like Paperblog is the lack of automated deployement tools, like what Capistrano is for Rails. But Capistrano is designed to be flexible, this is how to get it able to deploy Django project.
Installation
The best way to install Capistrano is to use rubygems :
sudo apt-get install rubygems ruby ruby-dev
sudo gem install capistrano fastthread thermios
Recipe
Before going a step further, this is basically how Capistrano works. Capistrano is watching for a file named Capfile in the root directory of your project.
This file contains all the recipes of your deploy, each recipes is composed of simple task that you can regroup, execute only on a certain kind of machine, render atomic, etc. For example :
namespace :deploy do
desc "Restarts your application"
task :restart do
sudo "/etc/init.d/apache2 reload"
end
end
Capistrano offers us already written tasks to deploy application from a subversion repository on n servers with distincts roles (app, web, db, etc.).
Some of them suppose that your are deploying Rails applications, so we only have to redefine them in order to make Capistrano able to deploy our sweet Django project.
Capify
To capify our Django project, we just need to create a Capfile file in the root directory of our project and add this line in order to import all predefined Capistrano tasks :
load 'deploy' if respond_to?(:namespace)
Before going further, take a look at the Capistrano’s predefined tasks documentation.
First of all, we need to declare some essential variables like : the subversion repository’s url, the name of our project, define role for each server, etc. Most of them are already documented, once again, take a look at the Rails documentation.
#REQUIRED VARIABLES
set :application, "myapp"
set :repository, "http://dev.example.com/myapp/trunk"
#ROLES
role :app, "production.example.com"
role :web, "production.example.com"
role :db, "production.example.com", :primary => true
#OPTIONAL VARIABLES
set :keep_releases, 3
set :deploy_to, "/var/www/myapp/"
set :group_writable, true
We finally just need to redefine task in order to feed our needs and our project. Let’s start by the obvious, task for start and restart :
namespace :deploy do
desc "Restarts your application"
task :restart, :roles => :app, :except => { :no_release => true } do
sudo "/etc/init.d/apache2 reload"
end
desc "Start the application servers"
task :start, :roles => :app do
sudo "/etc/init.d/apache2 start"
end
end
And then we need to adapt these rules for Django, don’t be afraid to change things to reflect your very own project or to add other task :
namespace :deploy do
after 'deploy:symlink', 'deploy:files'
desc "Install settings and media files"
task :files, :roles => :app, :except => { :no_release => true } do
run "ln -nfs #{shared_path}/system/settings.py #{release_path}/settings.py"
run "ln -nfs #{shared_path}/media/ #{release_path}/media"
run "ln -nfs #{shared_path}/cache/ #{release_path}/cache"
end
desc "[internal] Touches up the released code"
task :finalize_update, :except => { :no_release => true } do
run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
end
desc "Prepares one or more servers for deployment"
task :setup, :except => { :no_release => true } do
dirs = [deploy_to, releases_path, shared_path]
dirs += %w(system media cache).map { |d| File.join(shared_path, d) }
run "umask 02 && mkdir -p #{dirs.join(' ')}"
end
desc "Deploys and starts a `cold' application"
task :cold do
update
start
end
end
These tasks create 3 directory that will be keep between each deploy :
- media : is our MEDIA_ROOT
- system : will contain your settings.py
- cache : is our cache directory (in case you use django file cache)
The directory ”/var/www/myapp/shared/” will contains every file that are independant from your code or specific to your server. And each file will be linked to the current deployed version via a symlink.
The directory ”/var/ww/myapp/current/” is pointing to the latest ”release” of your project.
You are ready to deploy your Django project using Capistrano :
cap deploy
To make your life easier, this is a Capfile ready to server with some extras inside !
Download the Capfile example.