Running Rails with Puma and JRuby on Heroku

Last post I demonstrated setting up a Ruby on Rails app on Heroku, running with the Puma server. As I mentioned before, in order to get the most out of Puma you should use a Ruby implementation with real threads like JRuby or Rubinius 2. In this post we’ll repeat most of the previous steps, but this time we’ll use a Third-Party Buildpack and get setup with JRuby.

Create a new Rails 3.x app with JRuby

Note: I’m not covering the specifics other than telling you to use RVM or rbenv to setup JRuby (I’m running 1.6.7.2)

First create a new rails app

~$ jruby -S rails new heroku-jruby-puma
  create 
  ...
~$ cd heroku-jruby-puma
~$ git init

If you check your Gemfile, you should see some key differences:

  • instead of
    1
    
    sqlite3
    gem you have
    1
    
    activerecord-jdbcsqlite3-adapter
  • gem
    1
    
    jruby-openssl
    included
  • 1
    
    assets
    group includes
    1
    
    therubyrhino
    gem

Configure Rails to work with JRuby

Some adjustments are needed to get this new Rails app to play nice on Heroku with Puma. First, we can’t just use the

1
pg
gem; You need to use the
1
activerecord-jdbcpostgresql-adapter
instead. Add
1
puma
and set some configuration variables for Rails and we’re set.

Gemfile

...
gem 'activerecord-jdbcpostgresql-adapter'
gem 'puma'
...
group :development do 
  gem 'foreman'
  gem 'activerecord-jdbcsqlite3-adapter'
end

Note: here I left

1
activerecord-jdbcsqlite3-adapter
in the
1
development
group just as an example.

config/application.rb

...
config.assets.initialize_on_precompile = false

config/production.rb

...
config.serve_static_assets = true
...
config.threadsafe!

# Heroku log stuff
STDOUT.sync = true
config.logger = Logger.new(STDOUT)

Create Heroku app with JRuby buildpack

Heroku’s Cedar stack has no native language or framework; instead your sever is setup via a set of scripts called Buildpacks. Heroku provides buildpacks for Ruby, Node.js, Python and a handful of others, but you can also create or use your own Buildpack by using the

1
--buildpack
flag and providing a URL. Here we’ll use JRuby’s Heroku Buildpack from github.com/jruby/heroku-buildpack-jruby.

~$ heroku create heroku-jruby-puma \ 
  --buildpack https://github.com/jruby/heroku-buildpack-jruby.git  

  Creating heroku-jruby-puma ... done, stack is cedar  
  BUILDPACK_URL=https://github.com/jruby/heroku-buildpack-jruby.git
  ...
~$ 

Now when you push your code up, Heroku’s slug compiler knows how to package things an build them to use JRuby.

Add a Procfile

As I mentioned last time, a

1
Procfile
tells Heroku how to run your app:

web: bin/puma -p $PORT -e $RACK_ENV

Thats it! Commit your changes and push to Heroku like before:

~$ git push
  -----> Heroku receiving push
  -----> Fetching custom buildpack... done
  -----> JRuby app detected
  -----> Vendoring JRuby into slug
  -----> Installing dependencies with Bundler
  ...
  -----> Writing config/database.yml to read from DATABASE_URL
  -----> Precompiling assets
  ...
  -----> Discovering process types
       Procfile declares types -> web
  -----> Compiled slug size is 44.5MB
  -----> Launching... done, v7
         http://heroku-jruby-puma.herokuapp.com deployed to Heroku

  To git@heroku.com:heroku-jruby-puma.git
     6bced4f..383a7cc  master -> master
~$ 

Within a few moments you should be running on JRuby/Puma on Heroku. Notice that your slug size is significantly larger than a normal stock Rails app running on MRI. That’s because of 4th item you see above, “Vendoring JRuby into slug”.

Congratulations! You’re now running Rails with JRuby and Puma on Heroku.

See Also:

@ctshryock

About

My name is Clint Shryock. I develop things in Go and Ruby. I live in central Missouri, where the weather is beautiful 4 months of the year.
+-----------------+
|                       |
|      (ノ^_^)ノ      |
|                       |
|   ☜(゚ヮ゚☜)    |
|                       |
|     ౿(ఠ_ఠఎ)    |
|                       |
|        ಠ_ಠ         |
x                      x
  xxx           xxx
       xx    xx
           xx