Tuesday, February 15, 2011

Using Sinatra with Bundler to deploy on Heroku

I decided to try using sinatra for a small project I started the other day. I normally work in rails and host my personal projects on heroku. Since rails 3 came out I have also gotten hooked on bundler. I could not find any single source that documented how to use all of these together nicely. Here is how I got it to work.

Gemfile

The gemfile is pretty basic, set a source for gems and include the sinatra gem.

source :rubygems
gem 'sinatra'

config.ru

myapp.rb

This is the sinatra file. Note that I defined a class (MyApp). This is very important because our config.ru needs the class as a handle for the 'run MyApp' call. An alternative would be to use "run Sinatra::Application" in your config.ru file.

class MyApp < Sinatra::Base
get '/' do
'Hello world!'
end
end

Running locally

First make sure rack is installed, then run the following commands in the root folder and the app should be up and running locally.

bundle install
rackup

Deploying to Heroku

Just run the following commands in the root folder and the app should be up and running on Heroku.

Using Bundler with Sinatra and deploying to Heroku is definately a great combination of technologies. I would also recommend checking out PadrinoRB (http://www.padrinorb.com/), a framework we built on top of Sinatra that augments it's functionality, gives you bundler support out of the box and a lot of other useful features like an admin interface.

There is a bug where you say `require './myapp'`, because that means you want to require it relative to the directory you are currently in, but you actually want to require it relative to the config.ru file (ie if you ran this from a different directory, it would break).

Instead, you can `require File.dirname(__FILE__) + "/myapp"` which will require from the directory of config.ru

Or you can edit the load path so the directory is in it, and then require like normal, relative to that dir:`$LOAD_PATH.unshift(File.dirname(__FILE__)); require 'app'`

Alternatively, when you run your server, you could do `$ bundle exec rackup -I . config.ru` which adds the current dir (the dot, the relative path to the root of your app) to the LOAD_PATH when you start the app. I like this best, it keeps the code cleanest, and you can put it in a rake task so you don't have to type all that stuff out. The problem is that Herkou doesn't currently give you that kind of control (I think Celadon Cedar does allow you to specify this command, but haven't tried)