Ruby on Rails
Capistrano

Capistrano (formerly known as Switchtower) is a utility which may be used to automate the deployment of your applications.

Resources

Related

You might want to read LighttpdWithProcessScripts to understand how a web server, FastCGI and the script/process scripts work together.

Recipes

Upgrading/switching from SwitchTower to Capistrano

  1. gem uninstall switchtower (remove all versions)
  2. gem install capistrano
  3. For each of your Rails projects, do “cap -A .”, keeping your deploy.rb
  4. For each of your Rails projects, remove lib/tasks/switchtower.rake

Copied from: http://weblog.jamisbuck.org/2006/3/6/capistrano-1-1

Deploying subversion tags

If you want to deploy tags instead of subversion HEAD:

Clean SVN tag support for Capistrano 2

or

Deploying subversion tags using Capistrano

or

Another subversion tag support lib for Capistrano 2

Tips and Tricks

Troubleshooting

If Capistrano is giving you problems (either “malloc” problems or it just hangs) on OS X, try this: http://jamis.jamisbuck.org/articles/2005/09/24/switchtower-on-osx

see also: CapistranoOnWindows

SSL Authentication Errors on Setup

If you run into ssh authentication problems when using deploy.rb (“cap -v setup”), and you are using standard host-based authentication, then try setting following optional variables in your deploy.rb file:


set :user, 'remote-host-username' ssh_options[:port] = 22 ssh_options[:verbose] = :debug ssh_options[:username] = 'remote-host-username' ssh_options[:host_key] = 'ssh-dss'

I was seeing strange EOF, vm_malloc, and other errors which were all tied to failed authentication. After looking at all of the internet postings, I found some people were having problems due to ruby install conflicts, SSL sockets in the wrong place, gems installed without dependencies, etc.

Our problem was that net-ssh did not like us running as one user on the localhost (’bob’) and requesting an ssh session on the remote host as ‘remote-host-username’. The set :user, 'remote-host-username' was not working, so we added the ssh_options[:username] = 'remote-host-username' in conjuction with the ssh_options[:host_key] = 'ssh-dss'. Our rsa key on the localhost in ~/.ssh/known_hosts for the remotehost was valid, but we couldn’t authenticate. As soon as we switched to force a dss authentication, which in turn required the localhost to store a new dss key in ~/.ssh/known_hosts, the problem disappeared. In summary, the problem was caused because net-ssh did not like having an established key in known_hosts and/or we needed to override the remote host username flag for net-ssh.

svn: command not found, Part I

If svn appears in your $PATH on the appropriate machine, you should be able to type which svn on the machine and get a response. This means the problem is not a path issue, but probably a port/firewall issue.

We had this problem when our svn server was on a different network than our deployment server. As a result, we saw the following error/debug messages when testing capistrano with cap deploy.

deployment server

svn: Can't connect to host '###.###.###.###': Operation timed out

localhost

 ** [out :: ###.###.###.###] bash: line 2: svn: command not found

We were able to get the ’can’t connect’ message on the deployment server by capturing the capistrano bash commands executed by cap deploy and running them directly on the deployment server.

So, the problem was simply a port-forwarding/firewall issue. When capistrano invoked svn commands on the deployment server, the deployment server couldn’t reach the svnserver because the latter was on another network with a firewall (and we had forgotten to open up port 3690 and forward it to the svn machine).

This may be related to “issues on the mailing list”

svn: command not found, Part II

If your svn executable on the server isn’t on the default path that the SSH environment gives you (typically /usr/bin:/bin:/usr/sbin:/sbin), you’ll need to set up the :svn variable in your deploy.rb:


set :svn, "/usr/local/bin/svn"

So, if you’re using MacPorts, the line is:


set :svn, "/opt/local/bin/svn"

This comes courtesy of “Duncan Davidson’s blog”

svn: command not found, Part II.5

For Subversion at least, Capistrano also depends on Subversion being installed on your local client machine. The symptom I experienced when this wasn’t the case was that everything seemingly worked up until the update_code task. At that point an
error message along the lines of invalid file or directory indicating that the svn log —limit 1 command failed.

note that if you specify the svn path with the :scm_command setting, capistrano will look for svn in that location locally and remotely.

svn: command not found, Part III

If you use username/password authentication with svn, you’ll need to make a small adjustment to your deploy.rb to pick up the password. See the suggestions at “The View From My Hammock blog” (courtesy of James Buck, dead link).

We simplified the instructions to remove password prompting, so our ssh options in deploy.rb look like:


set :svn, "/usr/local/bin/svn"
set :application, "someapp"
set :repository, "svn://XXX.XXX.XXXX:3690/Users/svn/repository/#{application}"

set :scm_username, “someusername”
set :scm_password, “somepassword”

Deploying in a win32 Environment

Capistrano extensively relies on SSH, which makes it ideal in a *nix environment. However, it can be used from a win32 machine since it uses the ruby net-ssh gem – a ruby SSH2 client. Note: make sure you install the gem: “gem install net-ssh”!

In theory, it can also be used to deploy to another win32 machine, where an SSH server is running. I am currently using cygwin/opensshd with some success, but not complete yet. I’ll update here when done – or someone else can update if they get there first!

Keywords: deploy production online update
category: Glossary

load_keys_from error

If you get the following:

Then it’s because your known_hosts file has bad entries.

How to deploy Rails App on RailsMachine using Capistrano and Railsmachine gem

split deploy.rb into multiple files
lets say you want to split deploy.rb into multiple files and require it in. do the following:

in deploy.rb
require '/path/to/other/file.rb'

in ‘/path/to/other/file.rb’
Capistrano::Configuration.instance(:must_exist).load do

after “deploy:update_code”, “do:whatever”
desc “do whatever”
task :do_whatever do
sh “echo whatever”
end
end

~