⚠️ This article is outdated, please see the Middleman on Heroku – 2017 edition post for a more up to date guide on how to deploy Middleman sites to Heroku.
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:
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:
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 'https://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 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
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 => "build",
: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("build/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:
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:
Deploy your code to Heroku:
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:
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.