Heroku with ruby-aaws

The first step of migrating my Rails app to Heroku included only a reduced feature set.

I completely removed all parts dealing with the Amazon-API, because ruby-aaws could not be installed as a gem on Heroku. The ruby-aaws gem is build on Ruby >= 1.8.7 while Heroku is running 1.8.6 #fail.

I asked Ian Macdonald, the creator of ruby-aaws, if there might be a workaround for this problem. Ian told me that this should not be a blocker and pointed me to some things I should take care of.

How to make ruby-aaws run with 1.8.6

Here are the steps that I performed to get things running:

# install gemsonrails to freeze the gem into the app
sudo gem install gemsonrails

# go to your rails folder
cd rails/yourapp

# install gemsonrails for your app
gemsonrails

# freeze the app
rake gems:freeze GEM=ruby-aaws

This will freeze the gem into vendor/gems/. Then I removed the tests and the examples, because they are not necessary and contain code that won’t work.
The app won’t start up until I fixed some little load path error:

# vendor/gems/ruby-aaws-0.7.0/init.rb
# add amazon to the path
require_options = ["ruby-aaws", "ruby/aaws", "amazon"]

The ruby-aaws library expects some login-credentials for the Amazon-API which are usually stored in a ~/.amazonrc file. Since Heroku gives no access to a user home (at least I did not manage to get access to it), I worked around it by putting the file in the RAILS_ROOT and adding some glue code in Amazon::Config:

# vendor/gems/ruby-aaws-0.7.0/lib/amazon.rb
# add rails-file
config_files << File.join(RAILS_ROOT, '.amazonrc') if defined?(RAILS_ROOT)

The next thing to fix was the usage of String.bytesize, which is not available in 1.8.6:

string.gsub( /([^a-zA-Z0-9_.~-]+)/ ) do
  # replace .bytesize with .size
  '%' + $1.unpack( 'H2' * $1.size ).join( '%' ).upcase
end

Voilà!

Heroku with custom domain

I recently decided to switch my Rails hosting platform. I started Rails using a shared hosting solution from domainFACTORY. That solution did not quite fill my needs so i decided to give Heroku a try.

Switching to Heroku is an easy taks, at least if you know what you’re doing…

Using Heroku

The heroku documentation is pretty decent. You will find almost everything very well explained.

So I provide just a little wrapup of the steps I went through for integrating an existing Rails application:

# install heroku gem
gem install heroku

# go to your rails folder
cd rails/yourapp

# skip git initialization if your app is already under versioncontrol
git init
git add .
git commit -m "new app"

# create a heroku app with the name of your app unless you already have one
# the first call to heroku automatically prompts for your ssh public key
# enter your heroku and ssh credentials
# heroku will automatically add heroku git repository as a remote
heroku create yourappname

# check that heroku is added
git remote

# add heroku remote manually if it's missing
git remote add heroku git@heroku.com:yourappname.git

# push your changes to heroku and automatically start your app with this
git push heroku master

# check logs 
# if the app crashes, most of the times 
# it is a missing .gems file that heroku uses for gem-management
heroku logs

Configuring the domain

Once the app is up and running, the next step is to get the custom domain working with Heroku. Heroku provides serveral solutions for this task. The most flexible way seems to be the Heroku-Zerigo integration.

You only have to add the Zerigo name servers to your domain as an NS (name server) naming entry. For my domain www.phoet.de this looks like this:

www.phoet.de	NS	 	a.ns.zerigo.net
www.phoet.de	NS	 	b.ns.zerigo.net
www.phoet.de	NS	 	c.ns.zerigo.net
www.phoet.de	NS	 	d.ns.zerigo.net
www.phoet.de	NS	 	e.ns.zerigo.net

It takes some time until the changes are propagated through all the name servers. You can check it using the host command:

host www.phoet.de
# www.phoet.de is an alias for proxy.heroku.com.
# proxy.heroku.com has address 75.101.163.44
# proxy.heroku.com has address 174.129.212.2
# proxy.heroku.com has address 75.101.145.87

The Heroku addons take care of the rest, no setup or whatever:

# add the custom-domain addon
heroku addons:add custom_domains:basic

# add the zerigo-dns addon
heroku addons:add zerigo_dns

# add your domain to heroku
heroku domains:add www.yourdomain.com

Magic!

I write these lines, because I did not manage to do this withouth the fast Heroku support.