UPDATE: This post was written using Capistrano 1, which has since been superseded. An updated version—covering deployment of Drupal with Capistrano 2—can be found here.
It’s easy to get spoiled building rails apps. Tools like migrations make it so much easier to keep databases in sync, the way environments are managed helps considerably, and there’s Capistrano which makes rapid deployments a breeze. I miss those things when I have to work with other systems.
A few months back there had been a brief conversation about using capistrano with drupal and there are several blog posts (like this one) about using it with PHP. So today, tired of resolving folders full of uploaded files, I decided to write a quick deploy.rb to use capistrano with drupal.
I’m presuming here that we already have capistrano installed locally, that a recent version of drupal is set up on the server, and that we’re deploying to the sites folder. Within that we’re going to end up with capistrano’s standard ‘releases’ and ’shared’ folders, but in this case ‘current’ will actually take on the domain name of our app and shared will contain ‘files’ rather than the usual system, log and pids.
So here’s how it goes. Firstly we want to define some variables
set :application, "MyApp" set :site_name, "www.example.com" set :svn_user, "james.stewart" # I like to have capistrano prompt me for the password. # You can replace this with a standard assignment set :svn_password, Proc.new { Capistrano::CLI.password_prompt("SVN Password for #{svn_user}: ") } set :deploy_to, "/home/mp_app/public_html/sites" role :web, "www.example.com"
So far, so much like a regular deploy.rb file. But if we want the app’s folder within sites to be called something other than ‘current’, we’ll need to add:
set :current_path, "#{deploy_to}/#{site_name}"
So that’s our configuration taken care of. Next we need to override a few of capistrano’s default tasks since we probably won’t be wanting to restart lighttpd/fastcgi, or change the permissions:
task :set_permissions, :except => { :no_release => true } do # do nothing end task :restart do # do nothing end task :deploy do update # restart end
And finally we want to update the setup and update_code tasks to make use of our altered directory structure.
desc < <-DESC Update all servers with the latest release of the source code. All this does is do a checkout (as defined by the selected scm module). DESC task :update_code, :except => { :no_release => true } do on_rollback { delete release_path, :recursive => true } source.checkout(self) set_permissions run < <-CMD rm -rf #{release_path}/files ln -nfs #{shared_path}/files #{release_path}/files CMD # uncache the list of releases, so that the next time it is called it will # include the newly released path. @releases = nil end desc "Set up the expected application directory structure on all boxes" task :setup, :except => { :no_release => true } do run < <-CMD umask 02 && mkdir -p #{deploy_to} #{releases_path} #{shared_path} #{shared_path}/files CMD end
Now we can save this file somewhere appropriate and deploy new versions as simply as:
% cap -f /my/path/deploy.rb deploy
People using one sites folder to run multiple applications may need to make some further alterations so their ’shared’ and ‘releases’ folders don’t clash, but I’ll leave those as an exercise for the comments or related blog entries!

What! No comments? And this is one of Google’s top hits for “drupal capistrano”
I’m in the midst of drupal deployment hell. Is Cap still working out for you w/ Drupal?
Cheers,
Peter
Comment by Peter Burkholder — 16 March 2007 @ 6:05 pm
I haven’t done many drupal deployments since writing this, but my testing has continued to work. I’d love to hear of other peoples’ experiences.
Comment by James Stewart — 17 March 2007 @ 2:32 am
[...] a work on process » Using capistrano for drupal deployment (tags: php automation build) [...]
Pingback by manicwave.com » Blog Archive » links for 2007-04-28 — 28 April 2007 @ 7:23 am
I’m using Capistrano 2, which uses some slightly different conventions.
Here’s most of my initial config/deploy.rb file:
namespace :deploy do
task :set_permissions do
# do nothing (the permissions are probably fine)
end
task :start do
# do nothing (on the assumption that Apache is already started)
end
task :restart do
# do nothing (although it’s probably a good idea to reload apache)
end
task :migrate do
# do nothing (TODO: figure a nice Rails-style DB migration for Drupal)
end
end
Oh, and you can just leave the :svn_password unset if you want to be prompted for it — there’s no need to write the prompting code yourself :-)
Comment by Rob Hunter — 28 June 2008 @ 7:06 am
Thanks Rob. I’ve been meaning to post an update for cap 2 but hadn’t had a chance to yet.
Any luck working out a migration style approach for drupal?
Comment by James Stewart — 28 June 2008 @ 10:35 am
For anyone following these comments, you may be interested to know that I’ve published an updated tutorial at http://jystewart.net/process/2008/07/deploying-a-drupal-site-with-capistrano-2/
Comment by James Stewart — 23 July 2008 @ 10:09 am