How I deployed Middleman to Heroku
I've recently redesigned this website and it is now built using Middleman.
Middleman is a static site generator using all the shortcuts and tools in modern web development
This post is about how I deployed the site to Heroku.
Building the site
Middleman is a static site generator, as such, we need to figure out how to get the site built when we deploy. This saves having to build the site and commit the result before deploying.
Heroku will automatically attempt to execute a rake task called assets:precompile
.
This was originally for the benefit of Rails, but we can take advantage of this now for our own needs.
I created a new Rakefile
and added the following.
1
2
3
4
5
namespace :assets do
task :precompile do
sh 'middleman build'
end
end
The task simply shells out to call middleman build
which builds the site
automatically when the site is pushed to Heroku. Middleman will output all
files to ./build
.
Serving the site
The process of serving a static Middleman site on Heroku is quite straight
forward once you understand the basics. The site will be running as a Rack
app, so we'll need a config.ru
file. Here is what mine looks like.
1
2
3
4
5
6
7
8
9
10
11
12
13
require 'rack'
require 'rack/contrib/try_static'
# Serve files from the build directory
use Rack::TryStatic,
root: 'build',
urls: %w[/],
try: ['.html', 'index.html', '/index.html']
run lambda{ |env|
four_oh_four_page = File.expand_path("../build/404/index.html", __FILE__)
[ 404, { 'Content-Type' => 'text/html'}, [ File.read(four_oh_four_page) ]]
}
The Rack::TryStatic
section is how we serve up the static files that
Middleman builds when the site is pushed to Heroku. Middleman outputs all
files into ./build
.
If no page is served from the Rack::Trystatic
app, the 404 page is served
using the next run
section.
UPDATE: Make sure to add rack-contrib
to your Gemfile
as pointed out by
@fulljames.
I decided to use the Puma web server to do the actual web serving of the
files as I had never used it before and wanted to try it out. I added Puma to
my Gemfile
and created this Procfile
.
1
web: bundle exec puma -p $PORT
Puma is working great.
It's as simple as that. Once pushed to Heroku, everything just works.
Keeping the site alive
I'm using a single free Dyno to serve the site and it's seriously fast. Granted, this site is not receiving lots of traffic, but it's still very quick.
The only downside of a single Heroku Dyno is that it will idle after a period of inactivity, which can happen often unless you get lots of regular traffic.
I order to keep the site alive, the sites needs to be requested periodically.
I'm using Pingdom for this.
Conclusion
Middleman is really easy to work with, especially for a Rails developer, and Heroku serves the site very well. I would definitely recommend the combination of Middleman and Heroku.