Middleman on Heroku – 2013 edition

In case you haven’t heard of it yet, Middleman is a Rack-based static site generator built in Ruby. It’s super nice to use, but deploying it to Heroku can bit of a black art.

This guide assumes a few things:

  • You already have Ruby, RubyGems, and bundler installed on your system
  • You know the basics of Git
  • You already have the Heroku Toolbelt installed and configured
  • You already have an Heroku account
  • You know the rudiments of creating apps on Heroku

Step 1: Install Middleman locally

If you don’t have it yet, you should install Middleman on your development machine:

gem install middleman

For more details on this step, read the the Middleman documentation.

Step 2: Generate a new Middleman project

Generate a new skeleton Middleman app with a name of your choice (I chose clever_like_a_fox)

middleman init clever_like_a_fox

This will generate a ton of output, like this:

middleman init

Ignore this for now, and just do cd clever_like_a_fox and open the project directory in your editor.

Step 3: The Gemfile

Modify the Gemfile to look something like this (the Middleman version may vary):

# If you have OpenSSL installed, we recommend updating
# the following line to use "https"
source 'http://rubygems.org'

ruby "2.0.0"

gem "middleman", "~>3.0.13"
gem "rack-contrib"
gem "puma"

As you might notice, three lines have been added (ruby "2.0.0", rack-contrib, and puma). If you’re not using Ruby 2.0.0, you should set the Ruby version to the correct version.

Finally (for this step), run bundle install in terminal.

Step 4: The config.rb file

Next, we want to configure our app so that it builds into the right directory (only tmp is writable on Heroku) and so that we get pretty URLs (no .html at the end).

In the config.rb file, around line #50, above the set :css_dir and set :js_dir lines, add the following:

activate :directory_indexes

set :build_dir, "tmp"

Save your changes…

Step 5: The 404 page

We need to be able to give our users a nice error page if they go to a URL that doesn’t have content, so let’s create a simple 404 page file in the source folder (source/404.html):

<!doctype html>
<html>
<head>
  <meta charset=utf-8>
  <title>Page not found</title>
</head>
<body>
<p>The content you were looking for cannot be found.</p>
</body>
</html>

Once again, save your changes.

Step 6: The config.ru file

We’re almost there, just a little bit of configuration left!

Create a config.ru file in the root of your project and paste in the following code:

require "rubygems"

require "rack"
require "middleman/rack"
require "rack/contrib/try_static"

# Build the static site when the app boots
`bundle exec middleman build`

# Enable proper HEAD responses
use Rack::Head
# Attempt to serve static HTML files
use Rack::TryStatic,
    :root => "tmp",
    :urls => %w[/],
    :try => ['.html', 'index.html', '/index.html']

# Serve a 404 page if all else fails
run lambda { |env|
  [
    404,
    {
      "Content-Type"  => "text/html",
      "Cache-Control" => "public, max-age=60"
    },
    File.open("tmp/404/index.html", File::RDONLY)
  ]
}

Again, save your work.

Step 7: The Procfile

Create a new file called Procfile in the root of your project with the following contents:

web: bundle exec puma -p $PORT -e $RACK_ENV

Step 7: Deploy to Heroku

Woot! Almost there.

Add this line to the .gitignore file in the root of the project:

/tmp

Run git init . in the root of your project, then commit all the project files:

git add .
git commit -am "Initial commit"

Create a new app on Heroku:

heroku create

Deploy your code to Heroku:

git push heroku master

Open the URI given to you by Heroku, or run heroku open in terminal in order to open the site in your default browser.

You should be greeted by a site that looks something like this:

Welcome to Middleman

Notes

Heroku recommends using Unicorn to serve Ruby/Rack apps, but I chose Puma instead as it is simpler to configure. This will probably work well for most use cases.

The source code for my sample app is available on GitHub: matiaskorhonen/middleman-on-heroku. The code changes after each step have been tagged, in case you want to browse through the history.


By the way, you should also take a look my hobby project, Piranhas.

7 notes

  1. kambindm reblogged this from matiaskorhonen
  2. jonbaer reblogged this from matiaskorhonen
  3. matiaskorhonen posted this