Howto: Using Switchtower with Ruby on Rails and DreamHost
Sunday, January 22, 2006 at 7:31PM Rails][ror] applications. And, since my hosting company of choice is
[DreamHost][dh], I thought I'd share my recipe in case it was useful to others.
First things first, let's create the [Subversion][svn] repository. I'm actually
hosting my repositories over at [CVSDude][cvsdude] these days -- I got bored
waiting for DH to make an svn offering that people are clamouring for and they
offered me free space so long as I link to their site from my blog. Hence the
frog on the sidebar. Anyway, so I've created a brand new repository just for
this project, Stories, with the usual trunk, tags and branches layout. Create a
skeleton rails project in there, adding the necessary bits to the repository.
(Actually, maybe that's a future article, exactly how I setup my svn repository
for each new rails app.)
Let's configure things on the DreamHost control panel, since it'll potentially take a while for things to propagate there. Head to `Domains` -- `Manage Domains` -- `Add new domain / sub-domain` and create your new domain. For this example, I'm going to create [`stories.woss.name`](http://stories.woss.name/). Make sure to enable FastCGI support and, instead of accepting the default directory it suggests, append `/current/public`. ie the web directory in my case is:
/home/mathie/Sites/stories.woss.name/current/public
(I keep all my web sites in the `Sites/` directory for tidiness.) I always select to either add or remove the `www` from the address so that there's one canonical name, but that's just a personal preference. Add the domain and that bit's ready to go.
There's nothing terribly exciting about configuring the database. Head to `Goodies` -- `MySQL` and create a new database. I called the database `stories_production` ('cos somebody has already nicked `stories`!), on `db.stories.woss.name`. Sorted.
OK, while DH's pigeons are whirring away creating our shiny new domains and databases, let's head back to the Rails app. Edit `config/database.yml` and put appropriate development and test databases for your local machine. I use MySQL locally, since that's what I'll be deploying with on DreamHost. The production database should be the details you set up a few moments ago on DreamHost. You will also have to edit `config/environment.rb` and uncomment the line:
ENV['RAILS_ENV'] ||= 'production'
so that, when deployed, we default to the production environment. This is because the `RAILS_ENV` isn't explicitly set elsewhere in the deployed environment. The only other change we need to make to Rails itself is to modify the she-bang lines pointing to Ruby. Most of them (all the ones in the `scripts/` directory) are fine, but the ones in `public/dispatch.*` are wrong. Fix them up so they're `#!/usr/bin/env ruby` and we'll be fine.
Finally, we need to tweak `public/.htaccess` a little. Change the RewriteRule for the dispatcher (near the bottom) to use the FCGI dispatcher instead:
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
and add in a couple of rules immediately after `RewriteEngine On` to display a maintenance page if it exists on the file system:
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [L]
Commit your changes -- the next lot is to add Switchtower support itself.
To add switchtower support, run the following from your `RAILS_ROOT`:
switchtower --apply-to .
svn add config/deploy.rb lib/tasks/switchtower.rake
Edit `config/deploy.rb`, in particular setting the `:application` and `:repository` values correctly. All of the roles should point to the same machine: your newly created web host. `:deploy_to` should point to the top-level of the web directory you set up earlier (ie without the `current/public` bit at the end). Since we're running on a shared host, we don't want to be using `sudo` to restart things (it probably throws nasty warning things up in DreamHost's security logs!), we set `:restart_via` to `:run`). In fact, my complete, not-commented-out deploy.rb consists of:
set :application, "stories"
set :repository, "http://svn1.cvsdude.com/wossname/#{application}/trunk"
role :web, "stories.woss.name"
role :app, "stories.woss.name"
role :db, "stories.woss.name", :primary => true
set :deploy_to, "/home/mathie/Sites/stories.woss.name"
set :restart_via, :run
set :checkout, "export"
Dead simple. Commit that because we're ready to deploy! To set up the hosting platform, run:
rake remote_exec ACTION=setup
and every time you want to deploy a new version, run:
rake deploy
and it magically works! The functionality to enable and disable the site with `rake remote_exec ACTION=disable_web` and `rake remote_exec ACTION=enable_web` also works out of the box, if you happen to have completely screwed up the site you've just deployed. :-)
[st]: http://manuals.rubyonrails.com/read/book/17 "Switchtower manual"
[ror]: http://www.rubyonrails.org/ "Ruby on Rails"
[dh]: http://www.dreamhost.com/r.cgi?wossname
[svn]: http://subversion.tigris.org/
[cvsdude]: http://cvsdude.org/
Geekery
Reader Comments (10)
Bob: Yes, I have now incorporated the replacement
:restarttask, as topfunky suggests. I should update this article with all of the excellent suggestions you and others have made in the comments. Thanks!At the risk of sounding like a complete fool... I simply cannot get this to work. I'm about ready to pull my hair out because I've been fighting with Dreamhost all day trying to deploy my application with no dice.
I see that dreamhost has the switchtower gem installed but whenever I try to execute:
switchtower --apply-to .
in my svn.myhostname.com root folder I simply get:
-bash: switchtower: command not found
I'm stuck... again. What am I doing wrong? Any help is appreciated.
Dara
Historically, Capistrano was originally called SwitchTower. The name was changed in March 2006 in response to a trademark conflict.
I'm having the same problem as Dara -- the switchtower command doesn't work. Neither does cap -- and gem install capistrano results in permission denied. I don't understand...
[...] Howto: Using Switchtower with Ruby on Rails and DreamHost [...]
I get a error when running cap deploy:
D:/Program Files/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/lib/capistrano/scm/subversion.rb:24:in `latest_revision': Could not determine latest revision (RuntimeError)
Does it matter that my source is under:
http://svn.blablabl.com/share/projectname
and not
http://svn.blablabl.com/share/projectname/trunk
I have the same issue
rake aborted!
Could not determine latest revision
I run different OS with different version of capistrano
under ubuntu and with capistrano-1.2.0 and under suse with a previous version of capistrano i don't have this error
if I specify the revison number in my deploy.rb with for example "set :revision, 26" all it's ok
is it a konwn issue with capistrano-1.2.0 and dreamhost ?
This is a great help Graeme. One of the problems that I have run into (and I believe others have based on the comments above) is that the permissions on Dreamhost seem to be messed up during the deploy. In particular, the dispatch.fcgi does not get the execute (x) permissions necessary for operation. I also noticed that other permissions seemed to be too liberal, i.e. the world has read permissions on way too much of the rails app. I am assuming that there is a way in Capistrano to set the permissions. However, there must be a good 'default' setting for a project. Have you come across any good references and what do you do regarding setting permission? Thanks.
Howto: Using Switchtower with Ruby on Rails and DreamHost...
Switchtower is now known as Capistrano (as of March '06), but the article is still very useful for those that haven't upgraded to the most recent version of rails, and shows an interesting evolution from Switchtower to Capistrano. More recent......
If you're using a remote svn server, and svn+ssh:// urls, then you may get a "Killed by signal 15" message.
Changing :deploy_via, :export to :deploy_via, :copy should get around this.