Learn From My Pain: Deploying Rails on DreamHost

Since it seems like DreamHost is a pretty popular hosting solution for people who are getting into Ruby on Rails programming, I thought I'd try to give some advice on how to avoid the headaches. It took me 4 or 5 days to successfully deploy the most basic of web apps just because following the advice of kind strangers simply doesn't always work. So, I thought I'd provide some more kind stranger advice. This may be a little roundabout but it's a very predictable way to deploy, at least for me. Your milage may vary.

Let's walk through the easy way to set up a rails app at example.com - note that whereever I use example.com you should substitute your domain name. Double check that you have a directory in your file area that matches the domain name you're using (/home/username/example.com). Also, if you're a little rusty on Unix like I am, remember that whenever I use ~/ that means /home/username/ (where username is your DH username, of course).

  1. Make sure you're starting completely from scratch. We should have a vanilla domain setup in the DH control panel under "Domains > Domain Manager", and no files whatsoever in ~/example.com/
  2. Login to SSH and cd ~/
  3. Type rails example.com This will create a rails app at example.com which is setup up to run on the server, so it will know where ruby is installed, for instance, and what version of Rails is installed without you having to research it. Currently, DH runs Rails 1.1.2.
  4. Return to the Domain Manager and make sure FastCGI support is checked. Also, change the web directory path so that the entire path reads: /home/username/example.com/public/
  5. Wait a few minutes, then navigate in your browser to example.com. You should see the Rails welcome page.
  6. Return to SSH, and copy the app directory of your application into ~/example.com/app/
  7. Set up your databases in MySQL if you haven't already. Go to the DH control panel and navigate on the sidebar to "Goodies > Manage MySQL". Then create your database and also create a new hostname ("mysql.example.com"). Note the username (create a new one) and password you use. Go ahead and create a development, test, and production database so that your migration will work (you are using migrations, right?).
  8. Amend ~/example.com/config/database.yml to reflect your database setup. Make sure you change the host to mysql.example.com.If the database gives you problems and you're sure this file correctly reflects your database's account setup, you may find taking out the adapter line and putting in port: 3306 might help. It didn't for me, so try it without these changes first.
  9. Amend ~/example.com/config/environment.rb to ensure that there's a line like this at the top:
    ENV['RAILS_ENV'] = 'production'
  10. Check to make sure you have a route for the webroot in ~/example.com/config/routes.rb If not, uncomment this line:
    # map.connect '', :controller => "welcome"
    and fill in the controller which you want to handle any visits to https://example.com
  11. Modify all instances of dispatch.cgi in the ~/example.com/public/.htaccess file to dispatch.fcgi. In the current version of rails, there is only one line to change, on line 32:From:
    RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
    to:
    RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
  12. Dreamhost regularly kills off sleeping processes with their watchdog. This will kill your dispatch.fcgi processes, leading to Error 500s from time to time. You'll need to make dispatch.fcgi ignore all TERM requests by changing how it responds to them.After require 'fcgi_handler', change the rest of ~/example.com/public/dispatch.fcgi to read:
    class RailsFCGIHandler
    private
    def frao_handler(signal)
    dispatcher_log :info, "asked to terminate immediately"
    dispatcher_log :info, "frao handler working its magic!"
    restart_handler(signal)
    end
    alias_method :exit_now_handler, :frao_handler
    end
    
    RailsFCGIHandler.process!
    And save the file.
  13. At SSH,
    1. cd ~/example.com/
    2. chmod -R u+rwX,go-w public log
    3. Now run your migration, which will bring your database schema up to date: rake migrate
    4. rm ~/example.com/public/index.html
  14. You should be running!

If at first you get errors, give it a while. I had a problem where I followed these steps and couldn't get the webroot to route correctly (https://example.com was not being routed to my controller even though I specified it in routes.rb). I went to bed after messing with it for hours, woke up and tried it, and it was fine. So make sure that you give things time to fix themselves. Also, check the DreamHost Rails Deployment Wiki page for more tips and help.

Happy deploying!

Read this article
Written on Sunday, August 06, 2006