Wednesday, January 20th, 2010

Deploying Rails application using Capistrano and Phusion Passenger

Deploying a rails application onto the servers is a complicated task when performed manually, since it needs us to login to the servers, upload the code from the local system everytime and maintain the backup of the updates if we want to revert. This consumes a lot of time and we need to stop, start and restart the application servers everytime we need to update. This task can be simplified using these two deployment tools i.e Capistrano and Phusion Passenger (also called as “mod_rails”).


The installation procedure for both the tools are quite the same, since both tools are installed as the Rails gems. That is the speciality of Rails framework that it has all the required tools to operate build as gems. But the difference is that Capistrano helps to upload the code and deploy whereas Phusion Passenger is an Apache module which helps us to deploy a rails application on Apache a breeze. The installation of these tools are as shown below :


Steps to install Capistrano gem

#sudo gem install capistrano


This command installs the Capistrano gem and you can start using the Capistrano tool in your rails application to deploy it to the server.


Steps to install Phusion passenger

#su -


For installing the Phusion passenger we need to have root permissions because some files used for installing it needs to be compiled which requires the root permissions.

#gem install passenger


This command installs the Passenger gem. We don’t need Passenger to be installed in our local system in order to make use of it. We need the Passenger installed in the server system in which we are going to deploy the application. Since the Passenger is an Apache module we need to install the apache module for it using the following command.

#passenger-install-apache2-module


This command installs the Apache module for the passenger tool. While installing this, it checks for the various requirements unlike Capistrano gem installation.


There are dependencies which need to be installed to install the Passenger Apache module. We need not worry much about the dependencies since the installation process, by itself, checks for the availability of the dependencies and if not available, it will give us the commands to install the dependencies. We just need to follow the instructions it gives and Passenger will be installed and ready to use. During the installation it asks us to add some code to the Apache configuration file as below:

LoadModule passenger_module /somewhere/passenger-x.x.x/ext/apache2/mod_passenger.so
PassengerRuby /usr/bin/ruby
PassengerRoot /somewhere/passenger/x.x.x
PassengerMaxPoolSize 10


If we don’t wish to install those dependencies and abort in the middle then the installation terminates since the Passenger can’t run without those dependencies. Note that we just need Passenger installed in the server and don’t need it our local system. Once these two tools are installed, together they provide us a very flexible and easy way to deploy the rails application to any number of servers at a time.

To use Capistrano to deploy your application you need to capify your application using this command:

../rails_app # capify


Capistrano reads instructions from a capfile and processes them as given in it. Capfile is where you will tell capistrano about all the servers you want to connect to and the tasks you want to perform on those servers. The capfile contains a Ruby script augumented with a large set of helper syntax to make it easy to define server roles and tasks. The sample code of the capfile will look like this :

role :libs, “crimson.capify.org”, “magenta.capify.org”
role :files, “fuchsia.capify.org”
task :search_libs, :roles => :libs do
run “ls -x1 /usr/lib | grep -i xml”
end
task :count_libs, :roles => :libs do
run “ls -x1 /usr/lib | wc -l”
end

desc “Link in the production database.yml”
task :link_production_db do
run “ln -nfs #{deploy_to}/shared/config/database.yml #{release_path}/config/database.yml”
end


When we are using Capistrano we need to setup the structure of the application using the command below :

../rails_app # cap deploy:setup


When we run this command in our application the Capistrano will setup the application stucture. The application after deploying will have folders by names as shared, releases and a symbollic link called current which is pointing to the latest code of the latest release in the releases folder. Whenever we modify or update the code and we release through Capistrano it will add the new folder to the releases folder with the release version number (Version number will be based on the timestamp). The current sym-link will point to the latest release which contains the latest code.

The tasks written in Capfile is readable and its very easy to write these for a person who can work with command-line Linux shell. To view what are the tasks present in the capfile we should use this command which shows the self documented data:

#cap -T or cap -vT


(-v is for verbose descriptions)

This displays the list of tasks along with the descriptions as below:

cap deploy # Deploys your project.
cap deploy:check # Test deployment dependencies.
cap deploy:cleanup # Clean up old releases.
cap deploy:migrate # Run the migrate rake task.
cap deploy:pending # Displays the commits since your last deploy.

Consider that you have written the ruby script in capfile to deploy the application. Now if you want to deploy the application, you need to run this at the command prompt:

# cap deploy


Then according to the details of the servers and the path of the application specified in the capfile the Capistrano will deploy the application. If you are running mongrel application servers for each application then you need to write the command to start the mongrel server as a task in the capfile.
Suppose you are using Phusion passenger to run application then you need to add the task of starting and restarting the application using Phusion passenger into the capfile.

Desc “Start application”
task :start do
run “touch #{current_path}/tmp/restart.txt”
end

desc “Restart application”
task :restart do
run “touch #{current_path}/tmp/restart.txt”
end


The default environment on which the Phusion passenger runs the application is production, if we want to change the environment then we need to modify the RAILS_ENV in the environment file.

When you are using Phusion passenger which runs as an Apache module, it runs the spawn server for the application and on every restart operation it spawns the server with a new instance. Using Phusion passenger you can deploy application to a virtual host URI. For this you need to add the virtual host entry in the Apache configuration file as shown in the sample code below:

ServerName www.domain-name.com
DocumentRoot /webapps/rails_app/public

Allow from all
Options -MultiViews


While doing this we need to take care of the following conditions:

*The virtual host’s document root must point to your Ruby on Rails application’s public folder.
*The Apache per-directory permissions must allow access to this folder.
*MultiViews must be disabled for this folder.

If you want to deploy to a sub_URI, considering that we already have a virtual host then we need to add the code as shown below:


ServerName www.domain-name.com
DocumentRoot /websites/phusion

Allow from all

RailsBaseURI /rails

Options -MultiViews


And if you want your Ruby on Rails application to be accessible from some URL like http://www.domain-name.com/rails then you need to create a symlink from your Ruby on Rails application’s public folder to a directory in the document root.

For example:

#ln -s /webapps/rails-app/public /websites/phusion/rails


Once you create this symlink you will have to restart Apache and the application will have been deployed. You can deploy multiple rails application under a virtual host by specifying RailsBaseURI multiple times.

Once the application is started , if we want to restart the application we have to do either of these things:

a) Restart Apache webserver.
b) Use the command

# touch ../path_to_app/rails_app/tmp/restart.txt


Since we are using Phusion passenger which is an Apache module, the running log will be logged in both Apache error_logs and the application log file. Sometimes these wont be logged in the Rails applications log. In that case, you need to check the permissions and fix this problem by varying the permissions of the log file.

When you are using Capistrano with Phusion passenger you can deploy to more than one server at a time and even start and restart the application in a single run. Thus, it is much easier to deploy a Rails application using Capistrano and Phusion passenger.

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

2 Responses

Trackback

  •  
Get Adobe Flash playerPlugin by wpburn.com wordpress themes