Thursday, May 24, 2007

Deploying Rails to tomcat just works...

So, RailsConf 2007 is over, and I am back in Sweden again.
A lot of people in the blogosphere has summarized the different talks at RailsConf, so I won't do that right now.

For me, one of the best experiences from RailsConf is JRuby. I went to the tutorial "Your First Day with JRuby on Rails" on Thursday.
Ola Bini has continuously told us in the Rails community in Stockholm about the development of JRuby. But still, I was impressed of how easy you can turn a regular railsapp into a self-contained war-file running in an appserver, and using ActiveRecord JDBC. This is done with the goldspike-plugin on rubyforge.

Ok, so after the tutorial, I knew the theory, but does it really work for a real application?
Let's checkout!
I used a normal rails-app we use internally at my company.

Recipe
Here is a quick recipe for what I did to make it work:
(The assumption is that there is already a functioning railsapp using mysql on the computer, and that Java and ant, and tomcat is also installed.)

1. Install JRUBY (You can download a binary, or install it from source as is described here)
$ svn co svn://svn.codehaus.org/jruby/trunk/jruby
$ ant test
Add jruby to path:
$ export JRUBY_HOME =/Users/andreas/dev/jruby
$ export PATH=$PATH:$JRUBY_HOME/bin

2. $ cd "your-existing-railsapp-dir"

3. $ jruby script/plugin install svn://rubyforge.org/var/svn/jruby-extras/trunk/rails-integration/plugins/goldspike

4. Add support for mysql-jdbc:
Add to config/environments.rb:
require 'jdbc_adapter'

Add a new file config/war.rb with the following content:

maven_library 'mysql', 'mysql-connector-java', '5.0.5'

Add the following to each environment-description in config/database.yml :
adapter: jdbc
url: jdbc:mysql://localhost/blp_development
driver: com.mysql.jdbc.Driver


5. $ rake war:standalone:create
This will create a war file including a lot of java libraries (The jar-files that are needed are collected from maven repositories, including the mysql JDBC-driver specified in war.rb)

5. $ cp appname.war /opt/local/apache-tomcat-5.5.23/webapps/ (or wherever your tomcat is installed)

6. http://localhost:8080/blp

Voila, it works the same as the normal railsapp would, running in mongrel.
There is still some issue with static content, like css, but I am sure it will probably get fixed real soon. I haven't got any feeling of performance (it seems a bit slower then running it in mongrel), and other problems yet. But I am sure that backed up by Sun etc., the JRuby team will put a lot of energy in that (if it is an issue).

So why?
So, it works, but why would you use JRuby instead of standard c-ruby for railsapps?
Well, many customers I have shown small railsapps for has been impressed by the productivity boosts and how easy you can do things. But then they say "We can not have rails in our production environment, we are a Java shop".
My friend Peter has written a blog post that I think summarize "the why" pretty well.

The benefits of Jruby

  • Can use existing deployment environment in an organisation (if any, like Weblogic, jboss...)
  • Can use all existing Java-libraries out there from your railsapp...
Cons
  • Can not use native-c plugins , like ferret, rmagick... (This might be a problem if there are no alternative Java-libraries)

So, I look forward to see how this will effect the Rails-deployment strategies, rails adoption etc...

3 comments:

Raphaël Valyi said...

Hi, if you encounter problems with the new context path (URL is different from C RoR), you could try to deploy on the 'root context', for Glassfish you should enter '/' for the context name while you should name your webapp Root.war on Tomcat. I had this bug a few times ago and fixed it this way. I don't know if they fixed it though. Hope this helps.

Raphaël Valyi.

PS unfortunately, some stuff still sucks a lot, especially UTF-8 critical bugs both in JRuby RegExp and ar-jdbc are preventing non english speacking apps from being deployed...

Anonymous said...

Nice Work Andreas!

If you email your recipe to Chad Fowler, it may apear in his next book. I think tomorrow is the cutoff.

http://www.chadfowler.com/2007/5/2/contribute-to-advanced-rails-recipes

Andreas Ekström said...

raphael: Thanks, as a quick workaround it works to name the war "ROOT.war". (To get the context-paths right)

Mike: Nice to hear from you again, but I think this recipe is pretty standard, at least will be in a couple of weeks when 1.0 probably is released.