Web Developer's Virtual Library: Encyclopedia of Web Design Tutorials, Articles and Discussions


Java/Open Source Daily

jobs.webdeveloper.com

e-commerce
Partner With Us















Developer Channel
FlashKit.com
JavaScript.com
JavaScriptSource
Developer Jobs
ScriptSearch
StreamingMediaWorld
Web Developer's Journal
Web Developer's Virtual Library
WebDeveloper.com
Webreference
Web Hosts
XMLfiles.com

internet.com
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers


Automate Rails Application Deployment with Capistrano

Bookmark and Share

by Saurabh Bhatia

May 7, 2010

When you're ready to deploy your Ruby on Rails application, Capistrano can make the process much easier.

Capistrano, a deployment tool that helps to automate Rails application deployment, harnesses the power of metaprogramming to allow the user to define the values of deployment techniques, repositories, databases and exception notifications. In this article, I explain how to automate your Rails application deployment using Capistrano, Git (as the repository), and Phusion Passenger (as the server). I will use the demo Rails application from my previous article on Phusion Passenger.

How It Works

As in my previous tutorial, the Rails application to be deployed resides inside the /var/www directory. At regular intervals, Capistrano will work as follows:

  1. Run using cron.
  2. Go to the Git repository.
  3. Copy the source code to the specified folder (/var/www).
  4. Restart Apache2, loading the Passenger module.

It will also run the required migrations and modifications on the database, applying the domain name for the application. Capistrano does all this using SSH, a secure channel for carrying out this activity (see Figure 1 below). This means that the repository can reside in a remote location and applications can be deployed to another server.


How Capistrano Works
Click here for larger image

Figure 1. How Capistrano Works

Setting Things Up

Capistrano supports both Subversion and Git, but Git is becoming increasingly popular with Rails developers and actually replacing Subversion in a lot of places -- especially with GitHub making repository hosting so easy.

So, let's install Capistrano, Git, and Phusion Passenger:

saurabh@saurabh-laptop:~$ sudo apt-get install git-core 
saurabh@saurabh-laptop:~$ sudo gem install capistrano

Capistrano configuration is written in a file called deploy.rb, which sits in the config folder of the Rails application. This file contains various sections for configuring the source control system, the database, the server details and the DNS information. Now, set up SSH public key access between the systems. This ensures that the channel is safe and is accessed by the right people.

The Repository Setup

Subversion is the default repository of Capistrano, so we need to go to deploy.rb and change it to our taste. The contents of deploy.rb should look like this:

set :scm, :git 
set :application, "EmployeeInformationManager" 
set :repository, "git@safewlabs.com:eim-app.git" 
set :branch, "master" 
#set :scm_username, 'appman' 
#set :runner, 'appman' 
#set :use_sudo, false 
set :deploy_via, :copy

In the section of the file shown above, :application and :repository define the name of the application and the direct link to the repository. As a Git repository contains various branches, we need to define which branch to access in order to get the latest working copy of the code for deployment.

The :deploy_via command defines the deployment strategy. There are four kinds of deployment strategies:

  1. Copy allows people behind the firewall, which does not allow them to access their SCM over the network. The Copy strategy has some variables of its own. It checks the code out from the repository and creates a local copy of the version inside the directory to be deployed. It typically looks like this: /var/www/eim-app/releases/20101004215259/.
  2. Remote_cache enables speedier deployment because it places a working copy of the code in the cache of the server where it is supposed to deploy the application. It uses the cache function of the repository, matches the name of the deployment directory and the repository, and then deploys it.
  3. Export is a Subversion-specific command. It extracts a copy of the code from the HEAD. The exported repository cannot be updated via svn.
  4. Checkout also is a Subversion-specific command. It's used to perform a typical Subversion checkout inside the deployment directory.

Passenger Setup

The deploy to command defines the absolute path of deployment for the application.

set :deploy_to, "/var/www/#{application}"

The only thing that we need to define for Passenger is a way to restart the Apache server and restart the application when the changes are applied. This is because, like Mongrel, Apache does not identify the changes in the application out of the box and needs to load it in order for those changes to take effect.

Passenger (aka mod_rails) uses a simple method to restart. It needs us to create a simple file named restart.txt in the tmp directory of Rails. As soon as Passenger reads that file, the application restart takes effect; run "touch #{current_release}/tmp/restart.txt" does this for us. So, the deploy.rb looks like this:

namespace :deploy do 
  task :start, :roles => :app do 
    run "touch #{current_release}/tmp/restart.txt" 
  end 

  task :stop, :roles => :app do 
    # Do nothing. 
  end 

  desc "Restart Application" 
  task :restart, :roles => :app do 
    run "touch #{current_release}/tmp/restart.txt" 
  end 
end

Automating All This

Cron helps us to schedule the process of running Capistrano. We can simply define our Capistrano command in the cron edit and make it run every Friday at 18:30 hours.

saurabh@saurabh-laptop:~$ crontab -e

# m h  dom mon dow   command 
30 18   *   *   5   cap:deploy

The only thing we must do before completing this process is to assign the correct permissions to the server directory.

So, after we have written these directives, let's see what our deploy.rb looks like:

set :application, "EmployeeInformationManager" 
set :repository, "git@safewlabs.com:eim-app.git" 

set :deploy_to, "/var/www/symbid-app-23-jan/#{application}" 

set :scm, :git 

#set :scm_username, 'appman' 
#set :runner, 'appman' 
#set :use_sudo, false 
#set :branch, "master" 
set :deploy_via, :copy 

role :app, "myapp.com" 
role :web, "myapp.com" 
role :db,  "app_production", :primary => true 

namespace :deploy do 
  task :start, :roles => :app do 
    run "touch #{current_release}/tmp/restart.txt" 
  end 
 
  task :stop, :roles => :app do 
    # Do nothing. 
  end 

  desc "Restart Application" 
  task :restart, :roles => :app do 
    run "touch #{current_release}/tmp/restart.txt" 
  end 
end

Other Automations

The example we have gone through here makes deployment easier. However, you can simplify many other Rails tasks like migrations, database creation, and continuous integration with automated builds and failure notices.

About the Author

Saurabh Bhatia has been working with Rails since early 2006 and has a startup company, Safew Labs, that offers Rails consulting. He likes to write clean code, read and write.



Up to => Home / Authoring / Tutorials / Ruby on Rails