Sunday, May 8, 2011

Running Sinatra application on Tomcat

My recent fascination with the Sinatra framework has made me look for viable deployment options. At first I started with JRuby and Tomcat6.

So what do I need (top-to-bottom with only JDK installed) to successfully deploy a hello-world style application on Tomcat?

Installing prerequisites.

First you need a copy of JRuby and Tomcat6. Unzip both of them some place you'll have easy access to. In this tutorial I'll be using the root of drive C: because this is a folder everyone will have.
After doing so you should have 2 folders on your disk with the appropriate applications:

C:\apache-tomcat-6.0.29
C:\jruby-1.6.1

Installing required gems:

  C:\jruby-1.6.1\bin\jruby -S gem install sinatra sinatra-reloader warbler bundler

Creating the application.

Creating the hello-world style application (a bit extended version) is really simple. First you create a folder in a place of your choosing. In that folder you just need to create 2 files:

hello.rb:
  require 'rubygems'
require 'sinatra'
require 'sinatra/reloader' if development?

get '/' do
@message = "Hello, world! from Sinatra running JRuby on Tomcat"
erb :index
end

views/index.erb
  <h1><%= @message %></h1>
The hello.rb is the main application file and views/index.erb is the supporting view.
All further command line commands must be executed from the folder you've just created!

Testing if everything works as expected.

To test if the application performs as expected issue the following command inside the folder you have created:
  C:\jruby-1.6.1\bin\jruby hello.rb
and if there are no errors you'll have the application available on port 4567 right away. Test it with your favorite browser navigating to http://localhost:4567

Creating deployment files.

This is a little bit more involving. We'll create 3 files now:

Gemfile:
  source :rubygems
gem "sinatra"

config.ru:
  require 'rubygems'
require 'hello'

set :run, false

run Sinatra::Application

config/warble.rb:
  Warbler::Config.new do |config|
config.dirs = %w(views)
config.includes = FileList["hello.rb"]
config.jar_name = "hello"
end

The Gemfile is just the definition which gems are required by the application. The config.ru file defines how rack application is supposed to start. config/warble.rb is to tell the warbler tool which files go into the actual WAR file and what the output file name should be.

Create hello.war

To create the output hello.war file issue the following command:
C:\jruby-1.6.1\bin\jruby -S warble
At this point you should have the hello.war file ready for deployment.

Deploying to Tomcat.

This is the easy part. Simply copy the file hello.war to C:\apache-tomcat-6.0.29\webapps and start Tomcat.

Conclusion

It wasn't that hard, was it? Next time we'll see how we can do exactly the same with Apache HTTP Server and Passenger (a.k.a. mod_rails) running on a freshly installed Ubuntu 10.04.1.

And last but not least (because I know you've been waiting for it): the source code is obviously here for your entertainment :)

Have fun!

Edit on May 9th, 2011
I found out why specifying gem dependencies in config/warbler.rb doesn't work as it should and why the workaround with Gemfile is needed. Obviously for any bigger project it is better to use Gemfile and bundler as it solves the problem when another developer jumps in and wants to start hacking the application. For simple projects the config/warbler.rb should be enough though. Up until now specifying gems didn't work as expected due to an obvious bug in warbler. Here's a fix that I proposed to solve the problem:

https://github.com/padcom/warbler/commit/b4b24e17dee5bb98525203c82519a8901874ef81

With that in place the config/warbler.rb would look like this:
Warbler::Config.new do |config|
config.jar_name = "hello"
config.dirs = %w(views)
config.includes = FileList["hello.rb"]

config.gems = ["sinatra"]
end
and naturally the Gemfile would go away (one file less to keep track of :D in such a simple application)

No comments: