Home arrow Ruby-on-Rails arrow Page 2 - Application Deployment with Capistrano
RUBY-ON-RAILS

Application Deployment with Capistrano


In this conclusion to a five-part series on application deployment with Ruby on Rails, you'll learn how to create and use the Capistrano Deployment recipe. This article is excerpted from chapter 12 of the book Practical Rails Projects, written by Eldon Alameda (Apress; ISBN: 1590597818).

Author Info:
By: Apress Publishing
Rating: 5 stars5 stars5 stars5 stars5 stars / 4
August 25, 2010
TABLE OF CONTENTS:
  1. · Application Deployment with Capistrano
  2. · Running the Setup Task

print this article
SEARCH DEVARTICLES

Application Deployment with Capistrano - Running the Setup Task
(Page 2 of 2 )

To prepare the production server for deployment, we’ll use the setup task, which creates the required directory structure. To simulate a deployment to a clean environment, first delete the/udirectory we created earlier:

$ sudo rm -rf /u

Then kill any Ruby or LightTPD processes that might be running with the following commands:

$ sudo killall -9 /usr/bin/ruby1.8
$ sudo killall -9 lighttpd

By default, Capistrano deploys your application to the/udirectory. This directory can be created only by the root user, which means the deployment will fail if you run it now. To fix this, we’ll use a Capistranobeforefilter that creates the directory and then changes the access rights. Add the following task to the end of the deployment recipe (config/deploy.rb):

task :before_setup do
 
sudo "mkdir -m 770 /u"
 
sudo "chgrp rails /u"
end

Note that we use thesudocommand to create the directory. Earlier, we also added therailsuser to thesudoerslist.

Now run thesetuptask in the root of the application directory:

$ cap -a setup

--------------------------------------------    loading configuration /usr/lib/ruby/gems/1.8/gems/ capistrano-➥1.1.0/lib/capistrano/recipes/standard.rb
    loading configuration ./config/deploy.rb
 
* executing task before_setup
  * executing "sudo mkdir -m 770 /u"
    servers: ["192.168.0.1"]
Password:
    [192.168.0.1] executing command
    command finished
 
* executing "sudo chgrp rails /u"
    servers: ["192.168.0.1"]
    [192.168.0.1] executing command
    command finished
 
* executing task setup 
 
* executing "mkdir -p -m 775 /u/apps/emporium/releases➥
/u/apps/emporium/shared/system &&\n➥
mkdir -p -m 777 /u/apps/emporium/shared/log"
   
servers: ["192.168.0.1"]
    [192.168.0.1] executing command
    command finished
--------------------------------------------

By inspecting the output of the command, you can see that it executes thebefore_setuptask we added. If you log in to the remote machine, you will notice that Capistrano created the following directory structure:

$ tree /u

--------------------------------------------/u
`-- apps
   
`-- emporium
        |-- releases
        `-- shared
           
|-- log
            `-- system

6 directories, 0 files
--------------------------------------------

Note that you need to run thesetup task only once.

Deploying to Production

Now that we have run the setup task, we can continue and start the Emporium application on the production server. We could check out the source from Subversion and execute thespawnerscript manually, but instead, we’ll introduce you to thecold_deployCapistrano task.

Thecold_deploytask does exactly what we need: first it executes the Capistranodeploytask and then thespawnertask. Recall that thedeploytask checks out the source code on the remote machine and thespinnertask starts the FastCGI processes. Executerakeas shown here:

$ rake remote:cold_deploy

--------------------------------------------  (in /home/george/projects/emporium)  
    loading configuration /usr/lib/ruby/gems/1.8/gems/ capistrano-➥1.1.0/lib/capistrano/recipes/standard.rb 
    loading configuration ./config/deploy.rb
 
* executing task cold_deploy
  * executing task deploy 
 
** transaction: start
 
* executing task update_code
 
* querying latest revision... 
 
* executing "if [[ ! -d /u/apps/emporium/releases/20060813212006 ]];➥
then\n              svn co --username svn -q -r7 svn://localhost/emporium/trunk /u/apps/emporium/ releases/20060813212006➥
&&\n              (test -e /u/apps/emporium/revi
sions.log || touch /u/apps/emporium/revisions.log && chmod 666➥
/u/apps/emporium/revisions.log) && echo `date +"%Y-%m-%d
 
%H:%M:%S"` $USER 7 20060813212006 >> /u/apps/emporium/revisions.log;\n➥
           fi"
    servers: ["192.168.0.1"]
Password:
    [192.168.0.1] executing command
    command finished
 
* executing "rm -rf /u/apps/emporium/releases/20060813212006/log➥
 /u/apps/emporium/releases/20060813212006/ public/syste
m &&\n    ln -nfs /u/apps/emporium/shared/log➥
/u/apps/emporium/releases/20060813212006/log &&\n➥
ln -nfs /u/apps/empor ium/shared/system /u/apps/emporium/releases/ 20060813212006/public/system"
   
servers: ["192.168.0.1"]
    [192.168.0.1] executing command
    command finished
 
* executing task symlink 
 
* executing "ls -x1 /u/apps/emporium/releases"
    servers: ["192.168.0.1"]
    [192.168.0.1] executing command
    command finished 
 
* executing "ln -nfs /u/apps/emporium/releases/20060813212006➥
/u/apps/emporium/current"
    servers: ["192.168.0.1"]
    [192.168.0.1] executing command
    command finished 
 
** transaction: commit
 
* executing task restart 
 
* executing "sudo /u/apps/emporium/current/script/process/reaper"
    servers: ["192.168.0.1"]
    [192.168.0.1] executing command
 
** [out :: 192.168.0.1] Couldn't find any process matching:➥
/u/apps/emporium/current/public/dispatch.fcgi 
    command finished
 
* executing task spinner
 
* executing "sudo -u rails /u/apps/emporium/current/script/spin"
    servers: ["192.168.0.1"]
    [192.168.0.1] executing command
    command finished
--------------------------------------------

Capistrano will also restart existing FastCGI processes with thereaperscript, as you can see from the output of therakecommand.

Next, log in to the remote machine and use thetreecommand to display the directory structure created by Capistrano.

$ tree /u

--------------------------------------------/u
`-- apps
   
`-- emporium
        |-- current -> /u/apps/emporium/releases/20060516214952
        |-- releases
        |   `-- 20060516214952
        |-- revisions.log
        `-- shared
           
|-- log
            `-- system
--------------------------------------------

Theappsdirectory contains a separate directory for all applications that have been deployed. Now there’s only one directory for Emporium, which contains a subdirectory namedreleases.

Thereleasesdirectory is where your application is deployed into a directory named after the time and date the build was created. Thereleasesdirectory is not referred to directly by scripts; instead, they refer to the symbolic linkcurrent. Thecurrentlink is updated by thedeploy task and points to the latest version of your application.

The next time you deploy your application, you can runrake deployinstead ofrake cold_deploy.


Note  You should configure the Ferret search engine (introduced in Chapter 4) to store the index outside your application directory (for example,/u/apps/emporium/shared). This is because Capistrano deploys your application to a different directory each time you perform a deployment. If the index were in the application directory, Ferret wouldn’t be able to find it, and would create a new, empty one. One option is to put the indices inshared/index, and create anafter_deployhook that creates asymlinkfromcurrent/indextoshared/index.


Capistrano also has a built-in task that you can use for running database migrations during deployment on the remote machine. This means that you don’t need to create the database schema yourself, as you do when you deploy your application manually. Use the following command to run migrations along with the deployment:

$ rake remote:deploy_with_migrations

This checks out the latest version of the source on the remote machine. After the checkout has completed,rakeruns the migrations, which create the Emporium database.

Starting LightTPD

The last step we need to perform is to start up LightTPD, which acts as a reverse proxy for the FastCGI processes. Again, we’ll create a new task in our deployment recipe to save us the trouble of having to manually log in to the remote server(s) and execute the command each time we want to start the web server.

Add the following task to the deployment recipe (config/deploy.rb):

task :start_lighttpd, :roles => 'web' do
  sudo "lighttpd -f /u/apps/emporium/current/config/lighttpd-production.conf"
end

Notice that we have told Capistrano to run the task only on servers having thewebrole.

Next, run the task by executing the following command:

$ cap -a start_lighttpd

--------------------------------------------
    loading configuration /usr/lib/ruby/gems/1.8/gems/capistrano-➥1.1.0/lib/capistrano/recipes/standard.rb
   
loading configuration ./config/deploy.rb
 
* executing task start_lighttpd
  * executing "sudo lighttpd -f➥
/u/apps/emporium/current/config/lighttpd-production.conf"
    servers: ["192.168.0.1"]
Password:
    [192.168.0.1] executing command
   
command finished
--------------------------------------------

You should see the script complete successfully.


Tip  You should need to start LightTPD web server only once. Rebooting the machine will, of course, kill your processes, so remember to create a start script that runs at reboot and that starts LightTPD and thespawnerprocess.


Open Emporium in your browser and do a quick test. You shouldn’t see any errors, which means that you have completed the deployment.

Before we wrap up this chapter, we should tell you that FastCGI processes are known to start acting crazy once in a while. The only option, usually, is to restart the processes. This is one of the reasons why you should install a system monitoring tool like Nagios (http://nagios.org/) or monit (www.tildeslash.com/monit/). These tools help you notice when things go bad—not only with FastCGI, but also with other processes and protocols.

Summary

In this chapter, you learned how to set up a real-world production environment. We showed you how to install LightTPD and FastCGI by compiling from source. We also explained how to configure LightTPD for use in a production environment. Then we showed you how to deploy an application manually. Finally, you saw how to automate the deployment process with Capistrano, which makes your life as a developer easier and drastically lowers the barrier for deploying new features into production (at least for procrastinators).

In the next chapter, we’ll show you how to tune an application’s performance. 


DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

blog comments powered by Disqus
RUBY-ON-RAILS ARTICLES

- Ruby-on-Rails Faces Second Security Flaw in ...
- Ruby 2.0 Prepped for February 2013 Release
- Why LinkedIn Switched from Ruby on Rails
- Adding Style with Action Pack
- Handling HTML in Templates with Action Pack
- Filters, Controllers and Helpers in Action P...
- Action Pack and Controller Filters
- Action Pack Categories and Events
- Logging Out, Events and Templates with Actio...
- Action Pack Sessions and Architecture
- More on Action Pack Partial Templates
- Action Pack Partial Templates
- Displaying Error Messages with the Action Pa...
- Action Pack Request Parameters
- Creating an Action Pack Registration Form

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2018 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials