Deploying Ruby on Rails with Capistrano on DreamHost

When I set up my latest application on DreamHost, I had a real pain of a time. Most of the references I found for help were written in 2006 and referred to outdated commands. Since top Google results for “dreamhost capistrano ruby on rails” are mostly no longer adequate, I hope to help out anyone else who finds themselves in my shoes!

I first got good help from this resource at Rubynoob which references the Dreamhost Capistrano Wiki article.

With those two links and a bit of help from me, you should be all set. To make things quick, let me summarize the key points:

  • Set up your app with Fast-CGI enabled
  • Set up your own RubyGems following this resource
  • Also check out this resource for general Ruby on Rails + DreamHost concerns
  • “cap –apply-to .” is now “capify”
  • Download my deploy.rb file or read from it below for good explanation of what most of the items do.
  • Set up your processes as shown below
  • Make sure every file in your /script folder has the first line: #!/usr/bin/env ruby
  • Make sure every file looking like /public/dispatch* has the first line: #!/usr/bin/env ruby

My deploy.rb file:

# The host where people will access my site
set :application, "test.gamelizard.com"
set :user, "my dreamhost username set to access this project"
set :admin_login, "my admin login name"

set :repository, "http://#{user}@svn.gamelizard.com/rgamelizard/trunk"

# If you aren't deploying to /u/apps/#{application} on the target
# servers (which is the default), you can specify the actual location
# via the :deploy_to variable:
set :deploy_to, "/home/#{admin_login}/#{application}"

# My DreamHost-assigned server
set :domain, "#{admin_login}@ajax.dreamhost.com"
role :app, domain
role :web, domain
role :db,  domain, :primary => true

desc "Link shared files"
task :before_symlink do
  run "rm -drf #{release_path}/public/bin"
  run "ln -s #{shared_path}/bin #{release_path}/public/bin"
end

set :use_sudo, false
set :checkout, "export"

# I used the handy quick tool to set up an SVN repository on DreamHost and this is where it lives
set :svn, "/usr/bin/svn"
set :svn_user, 'my svn username'
set :svn_password, 'my svn password'
set :repository,
  Proc.new { "--username #{svn_user} " +
       "--password #{svn_password} " +
       "http://svn.gamelizard.com/rgamelizard/trunk/" }

desc "Restarting after deployment" 
task :after_deploy, :roles => [:app, :db, :web] do
  run "touch #{deploy_to}/current/public/dispatch.fcgi" 
  
  run "sed 's/# ENV\\[/ENV\\[/g' #{deploy_to}/current/config/environment.rb > #{deploy_to}/current/config/environment.temp" 
  run "mv #{deploy_to}/current/config/environment.temp #{deploy_to}/current/config/environment.rb"
end

desc "Restarting after rollback" 
task :after_rollback, :roles => [:app, :db, :web] do
  run "touch #{deploy_to}/current/public/dispatch.fcgi" 
end

My script/process/reaper file:

#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../config/boot'
require 'commands/process/reaper'

My script/process/spawner file:

#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../config/boot'
require 'commands/process/spawner'

The permissions in the script/process folder should look like:

-rwxr-xr-x  1 Malohkan  staff  108 Jan  7 19:06 reaper
-rwxr-xr-x  1 Malohkan  staff  109 Jan  7 19:06 spawner

If they look like “-rwxr-xr-x@” as can happen on a Mac you’ll want to kill the file and re-create it with the same content. I think this happens due to copying files and is representative of the notion that only the current logged-in user can access that file. As a result, when Capistrano deploys the file, it will not have permission to run it.

If you have other issues or concerns that are not addressed here, please leave a comment and I’ll do my best to help further!

If you don’t like the trouble caused by dealing with Ruby on Rails on DreamHost, check out this article for some ideas of good alternatives!

27 comments ↓

#1 Paweł on 02.03.08 at 9:07 pm

If you’re deploying by any chance from Windows box as development machine you will probably require to include line below into deploy.rb to save time searching the fix to strange problem.

default_run_options[:pty] = true

The guy behind capistrano said it would be set by default in next release… (http://www.mail-archive.com/capistrano@googlegroups.com/msg02817.html)

#2 Ben Brumfield on 02.22.08 at 11:17 am

Did you have any luck getting cap deploy:migrate to run? I can run the same command Capistrano runs to work by hand on DH, but not via cap.

#3 Ben Brumfield on 02.22.08 at 11:58 am

Okay, turns out that the DH process killer is killing off my migrations somewhere random. I wish I knew how to avoid that thing.

#4 Glenn Ford on 02.22.08 at 1:22 pm

Ben: I am able to use cap deploy:migrate from my localmachine with this setup. As for the DH process killer, I’ve only hit that when trying to install gems with “gem install”.

I guess this just means your migrations are taking a while! Sometimes giving it an extra couple of tries might get it to work, but you might want to consider (if possible) ssh’ing in, and manually moving migration scripts in 1 at a time so each time you run cap deploy:migrate it only has to run 1 migration script at a time.

If you are only running 1 migration script and it really is taking that long, I’m not sure exactly what to suggest. I don’t know what the rules are for the DH process killer in determining what should die. If I could figure that out then there might be some ways you could modify the scripts to avoid its detection, such as ruby sleep commands scattered throughout so that it doesn’t take too high of a processor %age while it runs. Just an idea!

Good luck 🙂

#5 patrick lynch on 04.25.08 at 6:28 am

i will be deploying 4 Ruby on Rails applications…what will be the monthly charge to do this?
Thank you

#6 patrick lynch on 04.25.08 at 6:31 am

What source code control systems does Capistrano support and where can documentation be obtained for Capitrano?

#7 Glenn Ford on 04.25.08 at 7:24 am

@patrick: Using Capistrano doesn’t cost anything, but you will still pay your usual hosting fee through DreamHost. I have multiple RoR applications deployed as well and it doesn’t affect my hosting price.

As for source code control systems, Subversion is the normal one to use with Capistrano, however googling “capistrano git” shows plenty of people are getting it to work with Git as well.

You can find more information about working with Capistrano here:
http://capify.org/getting-started/basics

Or get more help at their Google Groups page here:
http://groups.google.com/group/capistrano

#8 James on 04.26.08 at 7:45 pm

I spent the better part of 2 days updating the Dreamhost Wiki’s Capistrano page to support and document usage with rails 2.0 and Capistrano 2.

http://wiki.dreamhost.com/Capistrano

I reworked much of your deploy.rb but did include your clever task for forcing production environment by uncommenting line 5 of environment.rb upon deploy.

I could be wrong, but I though the convention these days is to put tasks into your Capfile instead of the config/deploy.rb.

#9 Glenn Ford on 04.27.08 at 4:20 pm

@James great contribution! I’m sure everyone (myself included) appreciates your hard work 🙂 It looks a lot better now!

#10 hagope on 04.28.08 at 12:04 pm

@James => thanks for updating the wiki, I’ve been reading heavily…however, I find a few concepts tricky:
=> for subversion, how should you name the project ID, DH takes the PID then makes the SVN directory svn/PID (is this correct? when I run the ‘svn add Capfile config/deploy.rb’ I get error)
=> in deploy.rb does set :repository have to begin with svn?
=> DH automatically creates a dir /mydomain.com, is this the set :application?

I’m confused with dir structure, any clarification would be appreciated I’d like to update the wiki with a real-world example…thanks!

#11 Glenn Ford on 04.28.08 at 12:41 pm

@hagope: You can name the project however you’d like, but personally I set the subversion url to be svn.my_web_site.com/project_name

When you run the svn add command, you say you get an error. Can you tell us what the error is?

‘set :repository’ just needs to be accurate to match your actually svn address. It doesn’t HAVE to have ‘svn’ as the subdomain.

‘set :application’ should be for the url of your application. It should be what you type in the browser to get it. As you see in my example above, mine reads as ‘set :application, “test.gamelizard.com”‘

The DreamHost directory structure just maps the url you want to the directory you want. It pre-fills in its suggestion, but you can type in whatever you want.

#12 hagope on 04.28.08 at 2:39 pm

@Glenn => tks for feedback…

$cd blog
$ svn add Capfile config/deploy.rb
svn: ‘.’ is not a working copy
svn: Can’t open file ‘.svn/entries’: No such file or directory

The “blog” directory is an arbitrary directory (after running rails command), it is not the application (which should live in /mydomain.com?). Is this an issue?

My confusion stems from the fact that I am developing on my Mac box and not on DH server, I guess I hoped that Capistrano “deploys” my application TO the DH server, so I don’t understand why I am running commands on the server…I may be missing the point here… 🙂

#13 Glenn Ford on 04.28.08 at 2:49 pm

Ahh that means your project doesn’t have Subversion set up yet. Check this out to help get your app working with Subversion: http://railscasts.com/episodes/36

As for the directory being named blog, that’s totally fine. In the example I give on this page they don’t match up either.

By the way none of these commands you’re using here should be run on the server. You should be working with the deploy script and Capistrano commands all locally. The deploy script’s job is to take your files from Subversion, and put them on your server for you. However in order for it to have a Subversion repository to work with, you have to set that up first!

#14 hagope on 04.28.08 at 3:22 pm

Phew…I was following this note from the wiki, but looks like it has since be deleted:

“Note: This is done when you SSH to DH and NOT in your dev box… “

#15 hagope on 04.29.08 at 3:53 am

…very close to deployment, however, I’m hung up on the following error:
“Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)”
I’ve changed the ‘database.yml’ file to remove the ‘socket:’ and even tried new ones, yet I still get this error on the db:migrate step (I ran cap deploy:migrate)…any suggestions? 😉

#16 Glenn Ford on 04.29.08 at 11:47 am

hagope: did you include the trick to set the Environment to Production by uncommenting it in the environment.rb file? It sounds like it’s using the wrong information from the database.yml. You can check this yourself by ssh’ing in to the server, going to your app folder, and running the command manually. See what happens, and try something like “rake db:migrate RAILS_ENV=production”

#17 hagope on 04.29.08 at 6:20 pm

@Glenn: the environment.rb file looks okay, i’m deploying the app to ‘/home/#{user}/current/’ but it seems that your technique uses ‘/home/#{user}/#{appdomain}/’ not sure if that makes a difference…I’ve pastied:

http://pastie.caboo.se/189014

#18 Glenn Ford on 04.29.08 at 7:30 pm

that should only affect the folder that the files get deployed to. You can verify that’s working by logging in to the server and seeing if they went where you thought. The error report looks like your ruby code isn’t getting parsed correctly. You should check the resulting file structure on your server to see if that’s the case.

#19 Anthony Ettinger on 05.26.08 at 5:57 am

It appears that DH will kill your svn export command if it is to a remote host.

I got “Killed by signal 15” repeated trying to export from my home svn server:

$ svn export -q -r745 svn+ssh://mybox.dyndns.org/x/svn/todo/rails/test_myproject /home/username/test.myproject.net/releases/20080526103817 && (echo 745 > /home/username/test.myproject.net/releases/20080526103817/REVISION)
Password:
Killed by signal 15.

#20 Anthony Ettinger on 06.03.08 at 4:24 am

any easy work-around for the above comment is to use :copy instead of :export.

#21 Glenn Ford on 06.03.08 at 4:30 am

Good to know. Thanks for that Anthony!

#22 taelor on 07.07.08 at 2:40 pm

Phusion Passenger

I’m sure you’ve seen, and probably used, although I would love to talk to you about this some, i just recently bought a dreamhost account. Going through some major pains to get a Merb app running using Passenger and Rack.

PS Congrats on getting hitched man!

#23 Jody on 07.08.08 at 9:41 pm

For some reason when I run the deploy:cold it fails with a Access denied error.

Access denied for user ‘root’@’schweppes.dreamhost.com’ (using password: YES)

This happens when the rake command is run. Any ideas?

#24 Glenn Ford on 07.19.08 at 3:30 pm

@taelor: I’ve heard of it but haven’t set it up yet myself! I hope to try it out soon.

@Jody: My guess is that it’s not following the correct environment. I get that if I have RAILS_ENV=’development’ instead of ‘staging’ or ‘production’. Basically it pulls up your root database info from your database.yml instead of the one you mean for it to reach in deployment.

I recommend ssh’ing in using the same user/pass you have set up in your deploy script and running that rake command yourself to see what happens.

#25 amurmann on 08.12.08 at 2:19 pm

I have the exact problem as described by hapoge. Was this problem solved by someone?

#26 Ayres Narita on 10.09.08 at 7:48 pm

@hagope: I have had this same error using Dreamhost, Sometimes Your application depends on data that is available only on your development copy. Strangely when it happens the “Can’t Connect” error shows up on the logs… Just dump your local database into the development and check.

I hope that’s the case for you.

#27 dilip on 10.15.08 at 6:54 am

when i rub cap deploy every thing gets excute,but when i check the database through ssh the database is not updating. what is the problem.