Using Capistrano

 in
“We will encourage you to develop the three great virtues of a programmer: laziness, impatience, and hubris.”—Larry Wall, Programming Perl
Customising the Rails Recipe

Making new Capistrano tasks is straightforward, but the Rails recipe we used earlier probably contains 90% or more of what you need. In this case, it's best to customise the recipe rather than create one from scratch. We can do this by overriding specific tasks to customise the corresponding behaviour of the recipe.

I discovered this when trying Capistrano on our internal makefiles, which is where I do most of our code file management, database versioning and installation configuration loads. We use these for pretty much everything that isn't committing or editing files, so the idea that we also could deploy really quickly using Capistrano was just too tempting.

If you've read this far but are thinking, “cool, but we're not about to migrate to Rails”, customisation will make sense for you because you can override the tasks that try to do Rails-specific things.

First, try capify on a non-Rails project, but make sure you have a config/ directory where capify can put its deploy.rb file. Once capify has run, you can start trying the various cap deploy tasks we did above, but it all goes wrong when Capistrano starts whining about the Rails server not being present and about a Rakefile not being present.

This is because one of the tasks, deploy:restart, tries to restart the Rails server. Another of the tasks tries to run rake db:migrate. Your project probably will support neither of these, so you should override it by adding the following to config/deploy.rb:

desc "Do nothing"
deploy.task :restart, :roles => :app do
  # ...do what you like here... 
end

Intuitively, this is overriding the restart task in the deploy namespace, and everything inside the task (everything from do to end) can be edited as normal. You might want to restart your Apache server instead of the Rails server:

desc "Do nothing"
deploy.task :restart, :roles => :app do
        sudo '/etc/init.d/restart'
end

When you run cap deploy:cold, the Rails migrations are run to create the database. We override this to run our equivalent, which is:

deploy.task :migrate, :roles => :app do
        run "make data"
end

Conclusion

Capistrano provides a really simple way of deploying an application. It also can be used for anything involving remote servers: monitoring, arbitrary tasks, creating ad hoc backups and so on.

Thanks to Ruby's elegance, Capistrano can be extended in pretty much every way. The Rails recipe can be honed for non-Rails applications, and adding whole new recipes involves very little Ruby knowledge.

Finally, to make things even quicker, use SSH identities so you don't even have to log in to the remote servers. If you want to keep your identities somewhere nonstandard, simply add the following to your deploy.rb file:

ssh_options[:keys] = "/path/to/identity_file" 

This way, you can deploy your app using cap deploy and nothing else—now you really can master laziness.

Dan Frost is Technical Director of 3ev, a Web app development company in Brighton, UK. Alongside his work as a developer and technical architect in PHP, Java and all the usual stuff, he writes articles on Cloud computing, Rails and Web 2.0 technologies.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

cap'ing Rails projects on servers

Walther Diechmann's picture

Hi Dan,

nice article - do you have any 'advanced' setups, like this one?

role :app, "10.4.3.223", :primary => true, :user => "root"
role :web, "10.4.3.221"
role :db, "10.4.3.220"
set :gateway, "webserver.domain.tld"

set :repository, "git@10.4.3.222:#{application}.git"

why?

Because I cannot get my multistage deploy to work :)

All the blogs and articles I've come around, they all seem to focus on setups with all servers on one machine, and git somewhere entirely else (like github.com)

Best regards,
Walther

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState