deploy any site with capistrano from svn

Capistrano is a very cool web deployment tool initially built for the ruby on rails environment, more info can be found here.  However you don't just have to be coding in Ruby to use it, it will work with any web environment. I had been working on a php site with codeigniter, which I deployed this way. Of course you will need to have ruby installed on your server

It's crazy easy to do, just create a config folder in the root of your project and add the deploy.rb with your deployment recipe an example may look like this:

[code]
# This defines a deployment "recipe" that you can feed to capistrano
# (http://manuals.rubyonrails.com/read/book/17). It allows you to automate
# (among other things) the deployment of your application.

# =============================================================================
# REQUIRED VARIABLES
# =============================================================================
# You must always specify the application and repository for every recipe. The
# repository must be the URL of the repository you want this recipe to
# correspond to. The deploy_to path must be the path on each machine that will
# form the root of the application path.
require 'mt-capistrano'

set :user, 'myusername'
set :password, 'mypassword'
set :site, "myserver.com"
set :webpath, "mywebsite.com"
set :domain, "#{site}"
set :application, "#{webpath}"

set :scm_username, "svnusername"
set :scm_password, "svnpassword"
set :svn_username, "#{scm_username}"
set :svn_password, "#{scm_password}"

set :repository, "http://#{scm_username}@pathtosvnproject"

# =============================================================================
# ROLES
# =============================================================================
# You can define any number of roles, each of which contains any number of
# machines. Roles might include such things as :web, or :app, or :db, defining
# what the purpose of each machine is. You can also specify options that can
# be used to single out a specific subset of boxes in a particular role, like
# :primary => true.

role :web, "#{domain}"
role :app, "#{domain}"
role :db, "#{domain}", :primary => true

# =============================================================================
# OPTIONAL VARIABLES
# =============================================================================
# set :deploy_to, "/path/to/app" # defaults to "/u/apps/#{application}"
# set :user, "flippy" # defaults to the currently logged in user
# set :scm, :darcs # defaults to :subversion
# set :svn, "/path/to/svn" # defaults to searching the PATH
# set :darcs, "/path/to/darcs" # defaults to searching the PATH
# set :cvs, "/path/to/cvs" # defaults to searching the PATH
# set :gateway, "gate.host.com" # default to no gateway

set :use_sudo, false
set :deploy_to, "/home/#{site}/domains/#{webpath}/deploy/"
set :checkout, "export"

# =============================================================================
# SSH OPTIONS
# =============================================================================
# ssh_options[:keys] = %w(/path/to/my/key /path/to/another/key)
# ssh_options[:port] = 25

ssh_options[:username] = "#{scm_username}"
ssh_options[:password] = "#{scm_password}"

[/code]

essentially you can set variables and what you're doing is telling it where your svn repository is, giving it access to the svn, then giving it access to the server and telling it where to deploy the files from svn onto the server.

Then you can create a Capfile in the root directory of your project to do more detailed things like create shortcut links from files within the deployed directory to folders in and files in a shared directory. The Capfile can look like the following:

[code]
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }

load 'config/deploy' # remove this line to skip loading any of the default tasks

#
# Custom
#

# Deployment process
after "deploy:update", "deploy:cleanup"
after "deploy", "deploy:sort_files_and_directories"

# Custom deployment tasks
namespace :deploy do

desc "This is here to overide the original :restart"
task :restart, :roles => :app do
# do nothing but overide the default
end

task :finalize_update, :roles => :app do
run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
# overide the rest of the default method
end

desc "Create additional directories and update permissions"
task :sort_files_and_directories, :roles => :app do

# create syslink for globally accessed files and folders
run "ln -s #{deploy_to}#{shared_dir}/assets #{current_release}/assets"
run "ln -s #{deploy_to}#{shared_dir}/uploads #{current_release}/uploads"
run "ln -s #{deploy_to}#{shared_dir}/swf #{current_release}/swf"
run "ln -s #{deploy_to}#{shared_dir}/js #{current_release}/js"
run "ln -s #{deploy_to}#{shared_dir}/system/application/config/config.php #{current_release}/system/application/config/config.php"
run "ln -s #{deploy_to}#{shared_dir}/system/application/config/database.php #{current_release}/system/application/config/database.php"

# create upload and cache directories
#run "mkdir #{latest_release}/system/cache"
#run "mkdir #{latest_release}/uploads/"

# move config files
#run "mv #{previous_release}/system/application/config/config.php #{latest_release}/system/application/config/config.php"
#run "mv #{previous_release}/system/application/config/database.php #{latest_release}/system/application/config/database.php"

# move log files
run "mv #{previous_release}/system/logs #{latest_release}/system/logs"

# set permissions
#run "chmod 660 #{latest_release}/system/cache"
#run "chmod 660 #{latest_release}/system/logs"
#run "chmod 660 #{latest_release}/uploads/"
end

end
[/code]

In this example where you see, run "ln -s …", i'm creating links in the current active directory to folders in my project's shared folder, this is for files I'm not keeping on svn for things like uploads, assets, or the database.php and config.php files which describe linkage to database and server variables.

Then all you need to do is capify your project, in terminal navigate to the root of your project and run this command:

[code]
capify .
[/code]

Then to set up the remote file structure run this:

[code]
cap deploy:setup
[/code]

Then to actually deploy your website on the remote server run this:

[code]
cap deploy
[/code]

That's it, you should be sitting pretty!

Leave a Reply

Your email address will not be published. Required fields are marked *