Ok I finally got down to business on SwitchTower. (The guide is here)
I already migrated all of my projects over to the database migration system available with rails (which is seriously a life saver.)
SwitchTower is basically a ruby app that makes it dead simple to deploy your Rails app into production. Now that I acutally have a couple of apps that are ready for deployment I figured it was time to dig in and figure this stuff out.
Basically there are a number of ways you can handle deployment. The nice thing about SwitchTower is that is it a standard way. Meaning they have sorted out a lot of the structure and process for deployment while still giving you a lot of flexiblity depending on your deployment.
Windows Tips
Since my dev environment is Windows and my deployment is Linux - I ran into a couple of problems.
1. Make sure that you have installed the subversion command line programs. I only had TortoiseSVN installed and the scripts depend on being able to call svn from the command line.
2. Putty Agent helps a lot. Basically this is a small app that comes with PuTTY that lets you store ssh keys. Using it you can authenticate your keys and then SwitchTower will try those keys to get into the production system.
3. Some of the tasks have to be modified. (My version is here) Basically windows isn’t happy calling switchtower with a system command - it wants to call switchtower.cmd. This version fixes that problem.
Once I followed the instructions in the guide (plus making the above modifications) I was pretty much in business. I only ended up making a couple of other changes.
1. I added an after_update_code task to make sure that a symlink from the apache configs that are stored in the project is made to a place where apache expects it.
2. By default SwitchTower does a checkout on the code. I would prefer an export - since that gets rid of all the extra .svn files and removes any temptation I have to modify it in place. I’m not sure if I’m going to keep doing it this way - but either way it does show how easy it is to modify the behavior.
class SwitchTower::SCM::Subversion
# Export out (on all servers associated with the current task) the latest
# revision. Uses the given actor instance to execute the command. If
# svn asks for a password this will automatically provide it (assuming
# the requested password is the same as the password for logging into the
# remote server.)
def export(actor)
svn = configuration[:svn] ? configuration[:svn] : “svn”
command = “#{svn} export -q -r#{configuration.revision} #{configuration.repository} #{actor.release_path};”
run_checkout(actor, command) do |ch, stream, out|
prefix = “#{stream} :: #{ch[:host]}”
actor.logger.info out, prefix
if out =~ /^Password.*:/
actor.logger.info “subversion is asking for a password”, prefix
ch.send_data “#{actor.password}\n”
elsif out =~ %r{\(yes/no\)}
actor.logger.info “subversion is asking whether to connect or not”,
prefix
ch.send_data “yes\n”
elsif out =~ %r{passphrase}
message = “subversion needs your key’s passphrase, sending empty string”
actor.logger.info message, prefix
ch.send_data “\n”
elsif out =~ %r{The entry \’(\w+)\’ is no longer a directory}
message = “subversion can’t update because directory ‘#{$1}’ was replaced. Please add it to svn:ignore.”
actor.logger.info message, prefix
raise message
end
end
end
end
desc < <-DESC
Update all servers with the latest release of the source code via export. All this does
is do an export(as defined by the selected scm module).
DESC
task :update_code, :roles => [:app, :db, :web] do
on_rollback { delete release_path, :recursive => true }
puts “EXPORTING CODE”
source.export(self)
run < <-CMD
rm -rf #{release_path}/log #{release_path}/public/system &&
ln -nfs #{shared_path}/log #{release_path}/log &&
ln -nfs #{shared_path}/system #{release_path}/public/system
CMD
end
Now I can do “rake deploy” from my development box and the production system is updated properly. I’m hoping it stays this easy to work with - because frankly I’m never doing a rails app again without it.
January 24th, 2006 at 7:39 pm (subscribed to comments)
Total newbie here, but I am getting syntax errors when I put your example code beginning with “desc