a work on process

Using capistrano for drupal deployment

You are reading a post by James Stewart entitled Using capistrano for drupal deployment. It was posted on 14 February 2007 at 1:10 pm.

You can find more posts by returning to the index.

Filed under: Notes
Tagged: , ,

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!

Recommend this post:

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Related Posts

 

6 Comments »

  • 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

TrackBack URI

Leave a comment

Login Method

OpenID

Anonymous