Building a capistrano recipe into a rails2 application, to deploy Drupal clone sites (or other cloned web applications)

I needed to build a way to deploy Drupal sites to support a limited hosting application for http://socialmediaclassroom.com project.

I decided to build an application using http://www.capify.org/ (Capistrano). I thought about developing this in http://drupal.org/project/drush. However, time constraints dictated otherwise.

I ended up working on this with partner Paul B. Hartzog. Here is what we did:

First, we made a capistrano recipe to deploy the Drupal site, based on http://joshhuckabee.com/capistrano-meets-drupal Josh Huckabee's nice cap recipe for deploying Drupal sites with Capistrano. Josh's recipe is here http://joshhuckabee.com/files/capfile

We modified it to look like this:

role :root, "yoursite.com"     
     # set :gateway,"yoursite.com"
      set :user, 'root'
      set :password, 'password'	
      ssh_options[:port] = 22
      ssh_options[:username] = 'root'      
 
 
namespace :drupal do
  namespace :install do
 
    desc "Adds a new site to an existing drupal install"
    task :site do
 
# hard coded and passed in values for commands run below
      set :site_url, "#{site_name}"
      set :root_db_user, 'root'
      set :root_db_password, 'password'
      set :site_db_name, "#{site_name}"
      set :site_db_user_name, 'root'
      set :site_db_user_password, 'password'
 
 
 
      run "cp -r  /var/www/copy /var/www/drupal/#{site_url}"
      run "mysqladmin -u #{root_db_user} --password=#{root_db_password} create #{site_db_name}"
      run "gunzip < /var/www/db.gz | mysql -u #{root_db_user} --password=#{root_db_password} #{site_db_name}"
      run "cp /var/www/copy/sites/default/settings.php /var/www/drupal/#{site_url}/sites/default/settings_old.php"
      run "cp /var/www/drupal/#{site_url}/sites/default/settings_old.php /var/www/drupal/#{site_url}/sites/default/settings.php"
      run "cp /var/www/drupal/#{site_url}/sites/default/settings_old.php /var/www/drupal/#{site_url}/sites/default/settings1.php"		
      run "sed 's|$db_url = .*|$db_url = \"mysql:\/\/#{site_db_user_name}:#{root_db_password}@localhost\/#{site_db_name}\";|g' /var/www/drupal/#{site_url}/sites/default/settings_old.php > /var/www/drupal/#{site_url}/sites/default/settings1.php"
      run "sed 's|$base_url = .*|$base_url = \"http:\/\/yoursite.com\/drupal\/#{site_name}\";|g' /var/www/drupal/#{site_url}/sites/default/settings1.php > /var/www/drupal/#{site_url}/sites/default/settings.php"
      run "rm /var/www/drupal/#{site_url}/sites/default/settings_old.php"
            run "rm /var/www/drupal/#{site_url}/sites/default/settings_old.php"	
    end
 
  end
end

The above script would normally be run from command line as:

$cap drupal:install:site

The above capfile needs be named "capfile", and to live in the rails "/lib" directory if you want to run it from a rails appliction.

We needed to run it when an entry in a rails application is created.

So, we ran:

rails drupal_clone

..to create a rails application, created scaffolding, and then created a class that runs our capfile, and placed that class in a ".rb" file in drupal_clone/lib directory of the rails apllication.

Our class looks like this:

class Clone
	attr_reader :var
	def initialize(site_name)
		@site_name = site_name
		@var = `/usr/local/bin/cap -s site_name=#{@site_name} -f ~/drupal_clone/lib/capfile drupal:install:site`
	end
end

Full paths were needed to make the capfile run from this class. YMMV.

Then, in the controller, we added:

def create
 
    @site = Site.new(params[:site])
    @clone = Clone.new(@site.site_name) #this is the new line we added
 
 
 
    respond_to do |format|
 
      if @site.save
 
 
 
 
        flash[:notice] = 'Site was successfully created.'
	format.html { redirect_to(@site) }
        format.xml  { render :xml => @site, :status => :created, :location => @site }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @site.errors, :status => :unprocessable_entity }
 
      end
    end
  end

This runs the capfile when "create" button is clicked in drupal cloning application.

That's it! This leans heavily on the capistrano toolset to do it's job, but it works well. We will be adding to the Rails application, including adding admin login, and emailing from the rails application when a new drupal site clone is created. Eventually, we will make an application requesting a new drupal site, plus an internal new site approval process in the rails application.

Finally, we'll be releasing this code under the GPL2 license, and making it available to download and install for people that want to host instances of http://socialmediaclassroom.com