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
- 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.
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.rb, staging.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/