Introduction

Capistrano is a Ruby tool that can be used to deploy Drupal site to multiple servers. It also allows you to run scripts on remote servers easily. Combined with drush it becomes a very good tool for handling Drupal sites.

You'll end up working on the site on a development server - installing modules manually or with drush, enabling them, etc. You can go to your development site with your browser and play around. You'll try to make sure all the configuration information is exported as code using features, installation profiles, etc. You'll be able to import the database from staging or production servers and try things out. Everything (except the database, files directory, settings.php) will be tracked with git.

When you want to move a site to the staging server, you go to the command line on your development server and say

bash> cap staging deploy

This goes to the site on the staging server, puts the site offline, backs up the database, moves a copy of the site to a new revision directory, points the domain name at the new revision, sets up some symbolic links to files, private_files, settings.php, does an update.php in case modules changed, reverts all the features in case they changed, makes a new git tag for the deploy, clears the cache, puts the site back on line, and a few more things.

If something screws up, you can say

bash> cap staging deploy:rollback

and the process is reversed, including restoring the database to it's original state.

Setting this up requires making a git repository for each site, creating a specific directory structure for the site on your development server, setting up a web accessible symbolic link, and tweaking the Capistrano configuration files to describe your staging & production servers. Through a combination of Puppet and Capistrano the staging and production servers get set up automatically.

Your Development Environment

Setup   
I had a lot of trouble with online recipes not matching the version of Capistrano I had. I settled on Capistrano v2.15.5 since that's what the Blacklight project is using. (capistrano-ext hasn't changed since 2008)
You'll need Ruby, Capistrano, PHP, MySQL, Git, drush, and a server to run the Drupal site. Here's how to setup MacOS.

Install capistrano and capistrano-ext (for the multi-stage feature):

gem install capistrano -v 2.15.5
gem install capistrano-ext

You've got to be able to ssh to the staging/production machines from your development machine without a password prompt for this to work. It's a common enough problem that you might want to take a look at drush's pushkey command. It's part of drush extras and the readme file shows how to install and use it.

   drush pushkey user@host.domain.com

           Creates an ssh public/private key pair in $HOME/.ssh, if
           one does not already exist, and then pushes the public
           key to the specified remote account.  The password for the
           destination account must be entered once to push the
           key over; after the key has been stored on the remote
           system, subsequent ssh and remote drush commands may be
           executed using the public/private key pair for authentication.

Local Directory  

Your development/site building happens here. It could be on a development machine also.

Set up a git repository for the site on https://git.library.cornell.edu/ - example https://git.library.cornell.edu/featureserver_test_library_cornell_edu

Next, push a local file into the repository to establish a connection with git.

mkdir featureserver_test_library_cornell_edu
cd featureserver_test_library_cornell_edu
git init
touch README.txt
git add README.txt
git commit -m 'first commit'
git remote add origin git@git.library.cornell.edu:featureserver_test_library_cornell_edu.git
git push -u origin master

Set up the local directory

  • Add these empty directories:
    • backup
    • drupal_config
    • private_files
    • public
  • Let capistrano create it's files and directories
    • capify .
      
    • (this creates Capfile and config/deploy.rb)
  • featureserver_test_library_cornell_edu
    • .git
    • .gitignore
    • README.txt
    • backup/ - place for backup files
    • drupal_config/ - a place for Drupal make file and module lists
    • private_files/ - point Drupal's private file directory at this directory (later)
    • public/ - put your Drupal site here (later)

Here's what my .gitignore looks like.

In our environment the public directory is a 'fake submodule' containing Drupal core and some standard modules:

 git clone --depth 1 git@git.library.cornell.edu:drupal_7_x.git public

Let capistrano create its default files

bash> cd featureserver_test_library_cornell_edu
bash> capify .

Now the directory looks like this:

.
├── .git
│   ├── COMMIT_EDITMSG
│   ├── HEAD
│   ├── branches
│   ├── config
│   ├── description
│   ├── hooks
│   ├── index
│   ├── info
│   ├── logs
│   ├── objects
│   └── refs
├── .gitignore
├── Capfile
├── README.txt
├── backup
│   └── README.txt
├── config
│   └── deploy.rb
├── drupal_config
│   └── README.txt
├── private_files
│   └── README.txt
└── public
  • Change the default deploy.rb to add stages (eg. staging, production) and add a deploy directory containing a file for each stage. Here are some examples for deploy.rbstaging.rb, and production.rb that work for CUL servers.You might as well plan to customize these .rb files to suit your server and site needs, even if you're new to Ruby. You'll need to at least modify the URLs and paths wherever there is a TODO comment.
    config
    ├── deploy
    │   ├── production.rb
    │   └── staging.rb
    └── deploy.rb
    

Now might be a good time to add all these new files into git.

bash> git add Capfile config/ drupal_config/
bash> git commit Capfile -m 'inital version from capify'
bash> git commit config/ -m 'staging and production deploy instructions'
bash> git commit drupal_config/ -m 'where to put Drupal make file and friends'

The Drupal Site

Next step: build the drupal site inside public/ including an installation profile we can use to build the site on a target machine.

Once you get the Drupal site set up you'll need to push that all into git also.

  • Build a make file and lists of modules in the drupal_config directory

Before the first deploy

Set up the staging/production server directories

bash> cap staging deploy:setup

This will create the directories on the staging server, move the site into place, make a copy of default.settings.php if necessary, set up symbolic links inside the files directory, and set file permissions. When it's done all the Drupal files are there and Drupal is ready to install.

Install Drupal

Go to the site with your browser and run install.php.

This is when it's really helpful to have made an installation profile for your site - you can select the profile and your done. If you don't have one, you have to go in and enable all the features, modules and themes you have enabled on your development server.

Final preparations

bash> cap staging drupal:post_install_configuration

This confirms that you have done the Drupal install, then sets up Drupal's public, private, and temp files paths, and does a final update.php.

A typical deploy

You are expected to have everything on your development site committed to git and your local git repo pushed to the central one before this happens.

bash> cap staging deploy

This will 

  • push a tag for this release to git
  • do a backup of the staging db (with the staging site offline)
  • update the staging server's clone of your git repo
  • check out all the stuff from the local git repo to a revision directory on staging
  • change the 'current' symbolic link to point to the public directory inside new revision directory
  • update symbolic links from the revision directory's public/sites/default/files
  • put the site offline
  • update the site's public, private, and temp files paths
  • run update.php
  • revert any features
  • put the site back online

References

http://www.58bits.com/blog/2013/03/23/deploying-drupal-with-capistrano

http://previousnext.com.au/blog/simple-and-powerful-drupal-site-deployment-capistrano

http://www.metaltoad.com/blog/capistrano-drupal-deployments-made-easy-part-1

http://www.zodiacmedia.co.uk/blog/professional-deployment-of-websites-using-capistrano-part-2

https://github.com/capistrano/capistrano/wiki/2.x-Default-Deployment-Behaviour

https://github.com/czettnersandor/drupal-cap

http://www.simonecarletti.com/blog/2009/09/capistrano-file-transfer-actions/

  • No labels