Understanding Deployment Strategies

Deployment strategies are just ways for capistrano to get your code onto your target servers, ready to rock and roll... there are currently four built-in strategies, some are better than others for large projects, some better than others for difficult network setups, be aware that they all have their pros and cons.

strategy.deploy!

it's only fair that you know what is going on under the covers.. the following headings explain how each one works, alternatives and the pros and cons of each. ( at least, in this author's opinion)

The deployment strategy is defined in the slightly misleadingly named :deploy_via variable (which I often confuse with the :gateway variable)

Examples:

set :deploy_via, :checkout
set :deploy_via, :copy
set :deploy_via, :export
set :deploy_via, :remote_cache

Deploy Strategy :checkout

Both checkout, and export should be familiar to users of subversion - since they directly reflect subversion commands.

In this case, your code is deployed to the server by capistrano issuing a "checkout" command, for example

# Example Settings
set :deploy_to, /u/apps/example
set :repository, svn+ssh://test.example.com/repository/trunk
# Example Command as run by Capistrano on your target server 
[host1.example.com]# svn checkout svn+ssh://test.example.com/repository/trunk /u/apps/example/releases/20081008215259/

Deploy Strategy :copy

The copy strategy is for those who struggle with a firewall or network problems stopping their deploy target servers not being able to access their SCM repository.

The copy strategy is designed to take a local copy (e.g. on the machine where capistrano has been invoked) of the code, and compress it somehow (You can use the :copy_compression variable outlined below to customise how) and copy it over scp to the target servers, where it is extracted to your :deploy_to location, to the usual "...../releases/20081008215259/" style directory.

The copy strategy comes with its own set of variables:

set :copy_strategy, :export
set :copy_cache, true
set :copy_cache, "/tmp/caches/myapp"
set :copy_exclude, [".git/*", ".svn/*"]
set :copy_compression, :gzip # Also valid are :zip and :bz2

Deploy Strategy :export

Both export, and checkout should be familiar to users of subversion - since they directly reflect subversion commands.

In this case, your code is deployed to the server by capistrano issuing an "export" command; which for those unfamiliar extracts a copy of the HEAD, minus the .svn metadata directories - rendering this an "exported" copy, rather than a working, versioned copy. "Exported" directories can not be "updated" from the repository with the likes of "svn update"

An example follows:

# Example Settings
set :deploy_to, /u/apps/example
set :repository, svn+ssh://test.example.com/repository/trunk
# Example Command as run by Capistrano on your target server 
[host1.example.com]# svn export svn+ssh://test.example.com/repository/trunk /u/apps/example/releases/20081008215259/

Deploy Strategy :remote_cache

Remote cache works by using a working copy of your code stored in a 'cache' on the target server(s) to speed up deployment.

Typically this uses the :repository_cache variable to identify where the cache will be stored, but this defaults to :shared_path + 'cached-copy/' (which is :deploy_to + 'shared/' by default)

# Example Settings
set :deploy_to, /u/apps/example
set :deploy_via, :remote_cache
set :copy_exclude, [".svn", ".DS_Store"]
set :repository, svn+ssh://test.example.com/repository/trunk
# Example truncated, capistrano does something clever to decide whether to create this repository cache, or just sync it
[host1.example.com]# svn update /u/apps/example/shared/cached-copy
# Then *ONE* of the following, depending whether or not you specified :copy_exclude
[host1.example.com]# rsync -rp --exclude=".svn" --exclude=".DS_Store" /u/apps/example/shared/cached-copy/* /u/apps/example/releases/20081008215259
[host1.example.com]# cp -RPp /u/apps/example/shared/cached-copy/ /u/apps/example/releases/20081008215259

Remote Cache works by targeting this directory, making sure it matches your :repository (in case you have changed the value of that variable) and updating it to the latest version, be that "git pull" or "svn update", will depend on your SCM.

It then proceeds to copy this code base to your :deploy_to location using either the "cp" command, or if you have specified exclusions (see below) rsync. Assuming this was all successful... capistrnao then runs the rest of your deployment script.

Extra variables:

set :copy_exclude, [".svn", ".DS_Store"]