nginx ❤️ Middleman

⚠️ 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 my last blog post about Middleman on Heroku, Middleman was configured to be served via the Puma application server.

By following this guide, you can setup your middleman site to be served by Nginx, which should be a lot more robust for static sites. If you already have a Middleman site in a git repo, you can skip the first few steps.

Install Middleman (if you haven’t already):

gem install middleman

Create a new Middleman site (and change into that directory):

middleman init beer_catalogue
cd beer_catalogue

Initialise the git repository and commit everything:

git add .
git commit -am "Everything"

Create a new Heroku app (if you omit the name Heroku will generate one for you):

heroku create beer-catalogue

Configure Heroku to use the multi-buildpack (with the Nginx and Ruby buildpacks):

heroku config:set BUILDPACK_URL=''
echo '' >> .buildpacks
echo '' >> .buildpacks
git add -f .buildpacks
git commit -m 'Add multi-buildpack'

Create a file called nginx.conf.erb in the config directory (create the directory if it doesn’t already exist) and give it the following contents:

daemon off;
# Heroku dynos have 4 cores.
worker_processes 4;

events {
  use epoll;
  accept_mutex on;
  worker_connections 1024;

http {
  gzip on;
  gzip_comp_level 2;
  gzip_min_length 512;

  log_format l2met 'measure#nginx.service=$request_time request_id=$http_heroku_request_id';
  access_log logs/nginx/access.log l2met;
  error_log logs/nginx/error.log;

  include mime.types;
  default_type application/octet-stream;
  sendfile on;

  # Must read the body in 5 seconds.
  client_body_timeout 5;

  server {
    listen <%= ENV["PORT"] %>;
    server_name _;
    keepalive_timeout 5;
    root <%= ENV["HOME"] + "/build" %>;

In the root of your project, update create the Procfile with the following contents:

web: bundle exec middleman build && bin/start-nginx -f sleep infinity

Commit these changes:

git add .
git commit -am "Nginx configuration"

And finally, push your Middleman site to Heroku:

git push heroku master

Once the push completes, you should be able to access the app at

HTTP Headers

If you want to, feel free to edit the nginx and Middleman config files to suit your needs (e.g. add additional cache headers or turn on directory indexes).