Rack + Puma + Heroku

Recently I have been working on the company's website(Icalia Labs), due to its lack of optimization on images, javascripts and stylesheets, so I decided to change that.

The website was built using Grunt to automate some tasks, my surprise was, not much of those tasks were actually being used and what is worse, there was no easy way to deploy it. It was too 'crafty'.

The website is hosted on Heroku as a rack application. And although everything was 'fine', the website was evaluated really low on simple metrics, like minified assets, too many requests for resources on the same server and some other stuff.


When it comes to deploy, I love Heroku, it is just great! They have amazing documentation on almost everything, but what I couldn't find was to correctly set a decent configuration for the website using rack and puma.

Although the solution is fairly simple, it took me a while to figure it out how to put all the pieces together.

The project tree looks like this:

icalia-website  
 |
 |- Gemfile
 |- Procfile
 |- config.ru
 |- public
      |
      |- assets/
      |- index.html
      |- ...the other pages

Giving this configuration which is the current one I manage to deploy the site on Heroku and improve its load time considerably. The file contents look like:

Gemfile:

# A sample Gemfile
ruby '2.2.1'  
source "https://rubygems.org"

gem 'rack'  
gem 'puma'  

Procfile:

web: bundle exec puma -t 5:5 -p ${PORT:-3000} -e ${RACK_ENV:-development}  

config.ru:

use Rack::Deflater  
use Rack::Static,  
  :urls => ["/assets/javascripts", "/assets/stylesheets", "/assets/img", "/assets/fonts"],
  :root => "public",
  :index => "index.html",
  :header_rules => [[:all, {'Cache-Control' => 'public, max-age=31536000'}]]

run Proc.new { |env|  
  [
    200,
    {
      'Content-Type'  => 'text/html',
      'Cache-Control' => 'public, max-age=31536000'
    },
    File.open('public/index.html', File::RDONLY)
  ]
}

As you can see there is nothing weird happening in here, I just setup my Procfile to run with Puma so if I run:

$ foreman start

the rack application will lift using puma as the server.

Another module I discovered while my optimization journey, is Rack::Deflater which compresses responses at runtime using deflate or trusty ol’ gzip.

This configuration really improved the website response times, therefore the user experience improved as well.

So I encourage you to try this configuration and let me know how it goes.