Sinatra Development and Production FastCGI Deployment

I recently found myself constructing (and considering the construction of) some simple web sites. I had no need for databases or authentication. I primarily wanted templates, to reuse HTML for header, footer, navigation menu, and sidebar. I also wanted to be able to turn these web sites into full-blown Ruby on Rails applications in the future if necessary.

Sinatra seemed like the perfect lightweight solution. However, the documentation of partials was pretty spotty. The Sinatra Book had what I needed and I rapidly reduced several large HTML files to a couple of templates and several small partials.

One major problem started when I needed to deploy the site to HostingRails. I had deployment of Ruby on Rails apps down, but they had no documentation on Sinatra apps. The best bet seemed to be this HOWTO for BlueHost. The main trouble was getting the

 require 'sinatra'

to work. The Sinatra gem was installed in my home directory and it somehow couldn’t be found when the web server tried to run dispatch.fcgi. I finally settled on the following content for dispatch.fcgi, combining lines from the Sinatra book with the HOWTO:

#!/usr/local/bin/ruby
#
# THE ABOVE LINE MAY REQUIRE MODIFICATION
#

# http://sinatra-book.gittr.com/#deployment_fastcgi
fastcgi_log = File.open("fastcgi.log", "a")
STDOUT.reopen fastcgi_log
STDERR.reopen fastcgi_log
STDOUT.sync = true

require 'rubygems'
require 'rack'

$LOAD_PATH << "/home/XXXX/ruby/gems/gems/sinatra-1.0/lib/"
#
# THE ABOVE LINE MAY REQUIRE MODIFICATION
#
require 'sinatra'

module Rack
  class Request
    def path_info
      @env["REDIRECT_URL"].to_s
    end
    def path_info=(s)
      @env["REDIRECT_URL"] = s.to_s
    end
  end
end

load "my_sinatra_app.rb"

builder = Rack::Builder.new do
  map '/' do
    run MySinatraApp.new
  end
end

Rack::Handler::FastCGI.run(builder)

The first line above may require modification based on where ruby is running in the hosting environment. The other line may require modification based on where the Sinatra gem is installed.

You need to redirect STDOUT and STDERR to a log file to examine production run-time errors.

This did require me to wrap my application in a class and save it in my_sinatra_app.rb.

class MySinatraApp < Sinatra::Application
  get '/' do
    "Hello, world!  It's now #{Time.now} at the server."
  end
end

The problem was, how to get this setup to work on my development machine? After reading through this presentation, I settled on the following and saved it as development.rb: </pre><pre> require ‘rubygems’ require ‘sinatra’ require ‘rack’

load “my_sinatra_app.rb”

builder = Rack::Builder.new do map ‘/’ do run MySinatraApp.new end end

Rack::Handler::Mongrel.run(builder, :Port => 3000) </pre>

Using the same my_sinatra_app.rb, I can run ruby development.rb on my development machine and use dispatch.fcgi on the server.

Tags: Uncategorized

Updated at: 26 September 2010 12:09 PM

NO COMMENTS ALLOWED