Capistrano Deployment
Capistrano is a tool used for automation of the application deployment process. Capistrano is mainly used for deploying rails apps. Changes made to the rails app can be easily transferred to the server using cap deploying. Capistrano can be configured with any version control system like SVN / GIT for deploying an app. Also, we can define application server type (mongrel, mod_rails / Fcgi) on which the app has be deployed in Capistrano. Here I’m going to discuss cap deploying an app using SVN with Mongrel cluster as the application server.
Installation:
Capistrano can be installed as a ruby gem as shown below:
$ gem install capistrano
Configuring a rails app to use capistrano:
This can be done by executing the following command from the rails app:
$ capify .
The above command will create a Capfile and config/deploy.rb file.
user@hostname [~/railsapp]$ capify .
[add] writing ‘./Capfile’
[add] writing ‘./config/deploy.rb’
user@hostname [~/railsapp]$ cat Capfile
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
user@hostname [~/railsapp]$ cat config/deploy.rb
set :application, “set your application name here”
set :repository, “set your repository location here”
# If you aren’t deploying to /u/apps/#{application} on the target
# servers (which is the default), you can specify the actual location
# via the :deploy_to variable:
# set :deploy_to, “/var/www/#{application}”
# If you aren’t using Subversion to manage your source code, specify
# your SCM below:
# set :scm, :subversion
role :app, “your app-server here”
role :web, “your web-server here”
role :db, “your db-server here”, :primary => true
PS: As an alternative, we can directly create Capfile and deploy.rb file under the rails app and load necessary data to it using ‘vi’ editor.
Capfile and Deploy.rb:
The Capfile contains all the tasks which has to be performed while cap deploying. All the functions (tasks) inside the Capfile can be defined using the keyword ‘task’. Group of functions is termed as namespace.
Sample Capfile:
load ‘deploy’ if respond_to?(:namespace) # cap2 differentiator
load ‘config/deploy’
namespace :deploy do
task :start, :roles => :app do
run “cd #{current_path} && mongrel_rails cluster::configure -e production -p #{mongrel_port} -N #{mongrel_nodes} -c #{current_path} –user #{user} –group #{user}”
run “cd #{current_path} && mongrel_rails cluster::start”
run “rm -rf /home/#{user}/public_html; ln -s #{current_path}/public /home/#{user}/public_html”
run “mkdir -p #{deploy_to}/shared/config”
run “mv #{current_path}/config/mongrel_cluster.yml #{deploy_to}/shared/config/mongrel_cluster.yml”
run “ln -s #{deploy_to}/shared/config/mongrel_cluster.yml #{current_path}/config/mongrel_cluster.yml”
end
task :restart, :roles => :app do
run “ln -s #{deploy_to}/shared/config/mongrel_cluster.yml #{current_path}/config/mongrel_cluster.yml”
run “cd #{current_path} && mongrel_rails cluster::restart”
run “cd #{current_path} && chmod 755 #{chmod755}”
end
end
The config/deploy.rb file contains all the variables which are used while cap deploying. Say, in the above Capfile we’re accessing different varibles like – mongrel_port, user, chmod755 etc the same should be first defined in the config/deploy.rb file then only Capistrano will execute the task properly.
Sample config/deploy.rb:
set :application, “railsapp”
set :domain, “hostname”
set :user, “user”
set :repository, “svn+ssh://#{user}@#{domain}/home/#{user}/svn/#{application}/trunk”
set :use_sudo, false
set :group_writable, false
set :deploy_to, “/home/#{user}/apps/#{application}”
set :deploy_via, :checkout
set :chmod755, “app config db lib public vendor script script/* public/disp*”
set :mongrel_port, “4000”
set :mongrel_nodes, “2”
default_run_options[:pty] = true
role :app, domain
role :web, domain
role :db, domain, :primary => true
Here we need to place the appropriate Application name, domain name and ssh user. The rails app should be imported to the svn repository before proceding the with cap deploying. SVN repository can be setup as shown below.
user@hostname [~]$ mkdir svn
user@hostname [~]$ svnadmin create ~/svn/railsapp
PS: Make sure to provide the same name of the rails app to svn repository too.
Once it is done we can import the rails app to svn repository:
user@hostname [~]$ mkdir -p ~/temp/railsapp/tags ~/temp/railsapp/branches
user@hostname [~]$ cp -pR ~/railsapp ~/temp/railsapp/trunk
Here make sure to provide the complete path to railsapp (Your rails app directory) while creating the trunk directory. Also the correct user, application and domain has to be given in the trunk/config/deploy.rb.
Rails app will be located in the trunk directory and it can imported to svn repository now.
user@hostname [~]$ svn import temp/railsapp file:///home/user/svn/railsapp -m “message”
The rails app imported to the svn repository (say, located at server) can be checked out to the local machine as shown below:
user@localmachine [~]$ svn co svn+ssh://user@hostname/home/user/svn/railsapp/trunk folder name
Password: SSH password of user
Now we can find the edited capfile and deploy.rb file in the checked out folder. After this, from the RAILS_ROOT of the local version application execute the following command.
$ cap deploy:setup
$ cap deploy:cold
The command ‘cap deploy:setup’ will setup the initial directory structure required for the cap deployed app.
Say,
/home/user/apps
/home/user/apps/appname
/home/user/apps/appname/releases
/home/user/apps/appname/shared
The command ‘cap deploy:cold’ will check out the rails app from the svn repository and place it under a directory inside – /home/user/apps/appname/releases. Later a sym link will be created from /home/user/apps/appname/releases/ /home/user/apps/appname/current. Also the document root will be pointed to the public directory of the current release as mentioned in the Capfile.
The release directory contains the apps deployed into the server and the app folder will be named according to the date and time on which the rails app has been cap deployed.
Say,
user@hostname [~/apps/railsapp/releases]$ ls -al
total 24
drwxrwxr-x 6 user user 4096 Apr 28 2009 .
drwxrwxr-x 4 user user 4096 Jul 9 2009 ..
drwxr-xr-x 16 user user 4096 Oct 15 2008 20081015183834
drwxr-xr-x 21 user user 4096 Feb 3 2009 20081015183941
drwxr-xr-x 8 user user 4096 Apr 28 2009 20090428215604
drwxr-xr-x 8 user user 4096 Apr 28 2009 20090428221701
Directories which are common in the rails app (say, images, configuration files, log files) are placed inside the shared directory and sym-linked to current release.
References:
http://www.capify.org/index.php/Capistrano
http://www.hostingrails.com/Capistrano-2-x-Deploying-Your-Rails-Application-on-HostingRails-com
Contributor : Vinayan