Rails on App Engine: A Cold Start

I’m at RailsConf ‘09 and I want to get a “Hello World” style Rails app running on Google App Engine, from a totally cold start, without any dependencies. A lot of this is available in various places on the net, including Dan Kubb’s sample Datamapper Rails app, and Ola Bini’s Rails on GAE post.
But I didn’t find anything that would get you through the whole process on one page, so as I beat my head against this (with lots of help!), I will put it all together, here. I got a lot of in-person help from @headius and @ridrdb, so lots and lots of thanks!
These steps are for Windows, but the basics are probably the same on any OS. Let’s go!
Step 1:
Install the latest Java JDK on your machine. You get no link from me here, I’m sure you can find it.
Step 2:
Download the JRuby complete package. The one I got was http://dist.codehaus.org/jruby/1.3.0RC1/jruby-bin-1.3.0RC1.zip
Step 3:
Unpack the zip into a convenient directory. I used C:/jruby, so you should, too.
Step 4:
I removed all my MRI (That means Matz’s version of the Ruby interpreter) directories from my path. I didn’t want to hit any Ruby stuff that wasn’t JRuby by accident. You can also prefix everything with jruby -S instead of doing this.
Step 5:
Put your jruby bin folder in your path (C:/jruby/bin)
Step 6:
Make sure JRuby works: Open a new console and type jirb.
>> 2+2
=> 4
>> exit
Step 7:
Install the gems you need:
gem install jruby-openssl rails warbler appengine-apis
Ola calls for gem install warble, which doesn’t work. Warbler includes jruby-rack, so you don’t need to download that separately.
Step 8:
We need the Google App Engine SDK. Get the one for Java:
http://code.google.com/appengine/downloads.html
And put it in your path somewhere
(I put it in c:/jruby)
Step 9:
Get Dan Kubb’s Rails App with datamapper
git clone git://github.com/dkubb/datamapper-on-rails.git
If you don’t have git you, can get the zip file: http://github.com/dkubb/datamapper-on-rails/commits/master and click download
Step 10:
Remove the DB gems from config/environment.rb
(sqlite3 and datamapper)
Add the gems you need:
config.gem 'rails'
config.gem 'appengine-apis'
Require the GAE apis gem’s logging
require 'appengine-apis/logger'
Set up GAE logging
config.logger = AppEngine::Logger.new
Once Datamapper 10 is out, @ridrdb’s datamapper interface for Google Datastore will work. Until then you can access Datastore directly from the Ruby API, but for the sake of this post, we’ll just punt on data storage at all, and use totally vacuous controllers.
Step 11:
Pluginize warble in your app
jruby -S warble pluginize
This didn’t work for me due to some Windows nastiness, so you can do this:
cd vendor/plugins
gem unpack warbler
Step 12:
jruby -S warble config
Step 13:
Edit your warble file similarly to the way Ola says to.
You need to set the parameters for how many runtimes will be started:
config.webxml.jruby.min.runtimes = 1
config.webxml.jruby.max.runtimes = 1
config.webxml.jruby.init.serial = true
The last option is available in trunk version of JRuby-rack. If you don’t have min=1 and max=1 then you need this option set, because otherwise JRuby-rack will actually start several threads to initialize the runtimes.
Set your environment to development mode:
config.webxml.rails.env="development"
If you use copy paste here, make sure your quote characters aren’t insane
Finally, to be able to use newer versions of the libraries, you need to set what Java libraries are used to the empty array:
config.java_libs = []
Step 14:
Use warbler to refactor your application setup
warble
This will break, but it gets far enough. It should create a tmp/war directory, which is your new application home
Step 15:
Move to your new home!
mv tmp/war ../warbled_dm_rails_gae
cd ../warbled_dm_rails_gae
Step 16:
Create a file called appengine-web.xml in your WEB-INF directory, with this in it:
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>msofaer-gae-test</application>
<version>1</version>
<static-files/>
<resource-files/>
<system-properties>
<property name="jruby.management.enabled" value="false" />
<property name="os.arch" value="" />
</system-properties>
</appengine-web-app>
Step 17:
Create your WEB-INF/lib directory
You need four jar files in it. Eventually warbler will handle creating them, but for now you can get the lib directory here:
http://github.com/MikeSofaer/rails_gae_lib/tree/master
Step 18:
Delete your vendor directory
Delete ActiveRecord from WEB-INF/gems/gems
Step 19:
Start the server
dev_appserver .
(If you’re not on Windows, dev_appserver.sh .)
Step 20:
Test the server
http://localhost:8080/rails/info/properties
You should get your env properties
| Ruby version | 1.8.6 (java) |
| RubyGems version | 1.3.2 |
| Rack version | 1.0 bundled |
| Rails version | 2.3.2 |
| Action Pack version | 2.3.2 |
| Active Resource version | 2.3.2 |
| Action Mailer version | 2.3.2 |
| Active Support version | 2.3.2 |
| Application root | C:/Users/mike/git/warbled/WEB-INF |
| Environment | development |
Now your application is running in dev mode! Add a route and a controller that does something, restart, and check it out. From here you can develop your app in a local environment just like GAE, until you deploy it.
Step 21:
Sign up for the Java GAE access:
http://appengine.google.com/promo/java_runtime
Eventually you will get an email, (keep developing on your local machine)
Step 22:
Jar up your application. Go to your gems directory (the first one)
jar cf ../lib/gems.jar gems specifications
Then delete your gems directory.
Step 23:
Create your application on the GAE panel:
http://appengine.google.com/start
Step 24:
Put your app ID into your app’s appengine-web.xml:
<application>rails-gae-test</application>
Step 25: Upload your app
appcfg update .
Step 26:
Go see your Rails app on app engine!
Here’s the tiny little controller response I built for testing:
http://rails-gae-test.appspot.com/responses
=> Hello, I hear you
So it’s been a long trip, and it’s not exactly pretty, but there it is. Victory!
Dan Kubb
Pankaj
msofaer, very well described!
I got the error following error,
javax.servlet.ServletContext log: unable to create shared application instance
org.jruby.rack.RackInitializationException: no such file to load — appengine-ap
is/logger
Thanks, Pankaj!
It looks like maybe I left off a step! I thought the logger API was included in the AppEngine API things you got from Google, but if it’s causing you a problem you can take out the lines that require it from config/environment.rb.
Let me know if that works!
Pankaj
Thanks msofaer!
I ran the app by commented the appengine-apis/logger.But getting following exception.I have installed the appengine-apis gem.What I am doing wrong?
…
…
Missing these required gems:
appengine-apis
You’re running:
ruby 1.8.6.287 at file:/D:/Rails2/JRuby/GAE/new/gae/war/WEB-INF/lib/jruby-stdl
ib.jar!/META-INF/jruby.home/bin/jruby.bat
rubygems 1.3.2 at D:/Rails2/JRuby/GAE/new/gae/war/WEB-INF/gems, file:/D:/Rails
2/JRuby/GAE/new/gae/war/WEB-INF/lib/jruby-stdlib.jar!/META-INF/jruby.home/lib/ru
by/gems/1.8
Run `rake gems:install` to install the missing gems.
Jun 4, 2009 1:31:07 PM com.google.appengine.tools.development.ApiProxyLocalImpl
log
SEVERE: [1244102467532000] javax.servlet.ServletContext log: unable to create sh
ared application instance
org.jruby.exceptions.MainExitException: aborted
…
…
Caused by: org.jruby.exceptions.MainExitException: aborted
The server is running at http://localhost:8080/
Jun 4, 2009 1:31:16 PM com.google.appengine.tools.development.LocalResourceFileS
ervlet doGet
WARNING: No file found for: /rails/info/properties.html
Pankaj
Try “gem install appengine-apis”
Pankaj
Hi msofaer,
It’s working now.I have generated the jar file of appengine-apis and included it under lib folder.
Can you provide some light on usage of datamapper?
Thanks
I’m glad it’s working!
I didn’t actually use Datamapper, since 0.10 wasn’t out yet (it is now) and is needed for the datastore adapter, so I can’t give you much guidance on using it for Google Datastore, other than to tell you it’s supposed to be supported. Once you get it working, you could make a blog post!
Pankaj
Thanks msofaer!
Our name is NJIT–New Jersey Institute of TEchnology. OUr “descriptor” is New Jersey’s science and technology...







Facebook
Twitter
Flickr
Subscribe
YouTube
SlideShare
LinkedIn
Delicious
Diigo
Newsletters
Wow, that’s quite alot of steps :)
In talking with the guys at Google, I think it’s safe to say they are really committed to making the process as simple as possible.
For my part I’m going to make it so DataMapper can be used with Rails with a drop-in plugin. It shouldn’t be too hard.. I think within the next week or so I should have something working well.