I use middleman for my own website. To make it easier for me to pickup my work over different machines , I added a small start script to the repository. In this article I’m going to show you how it works and how you can make use of it for your own website build on top of middleman.

Short introduction to “middleman”

middleman is a static site generator written in Ruby and it supports a wide variety of template languages such as ERuby, Haml, Markdown or Liquid – see the this README for a full list of supported template languages. It comes with a so called preview server. You can use this server during development to have a live view on your changes. If you prefer to have an updated site on each change made, you need to install and enable the livereload-extension.

Functionality of the script

The start script I added to my website’s repository has the following functionality.

  • Make middleman’s preview server listen on a random port to prevent collisions with other services running on the system
    • The port doesn’t require root-privileges to start the preview server
    • The script remembers the port over reboots of the system
    • The port configuration can be shared between different machines
  • Open your middleman-site in your favourite browser

To make those things possible, the script generates a configuration file I added to the git-repository. This file contains the port configuration. It is re-generated if it contains garbage.

Setup for the script

Please add a directory script/ to your middleman-site first.

mkdir -p script

After that add launchy to your site’s Gemfile.

gem 'launchy'

Now install all missing gems.

bundle install

Add the script

Then create a file named script/start.

#!/usr/bin/env ruby

require 'bundler'

require 'psych'
file = File.expand_path('../../.middleman-server.yaml', __FILE__)

  port = Psych.load_file(file).fetch(:port)
  $stderr.puts %(Reading server-config file "#{file}".)
  $stderr.puts %(Creating server-config file "#{file}".)
  port = (1_024..65_535).to_a.sample
  File.write(file, Psych.dump(port: port))
end "{port}"
system("middleman server -p #{port}")

To make use of the script, don’t forget to make it an executable.

chmod +x script/start

Then run it in some shell and see what’s happening.

# => Creating server-config file "/home/d/tmp/blub123/new_site/.middleman-server.yaml".
# => == The Middleman is loading
# => == View your site at "", ""
# => == Inspect your site configuration at "", ""

A detailed look at the script

The following code uses bundler to make sure that the correct version of the middleman-gem is used and that you don’t need to invoke the script with bundle exec.

require 'bundler'

To make middleman always use the same port, the script reads in the file .middleman-server.yaml and uses the information it found there to build the commandline of middleman server.

file = File.expand_path('../../.middleman-server.yaml', __FILE__)
port = Psych.load_file(file).fetch(:port)

If the file does not exist, does not contain the key :port or contains garbage, it is recreated by the script. In all given cases the following line will raise an exception and make the rescue-block run. #load_file will raise an exception if the file does not exist or is not a valid YAML-file. .fetch will raise an exception if no key :port is found.

port = Psych.load_file(file).fetch(:port)

The following code generates a random number in the range of 1.024 and 65.536. That makes sure, that no root-privileges are required to make middleman bind to that port: At least on UNIX/Linux operating systems – Mac OS X is also a UNIX – only root is allowed to bind services to ports which are smaller than 1.024.

port = (1_024..65_535).to_a.sample

After that, the newly generated port is written to the filesystem as YAML file.

File.write(file, Psych.dump(port: port))

To open your landing page in the browser, the script uses the gem launchy. The script assumes that middleman’s preview server listens on localhost ( – please change this to your needs if required. use means of your operating system to open the URL in your default browser. "{port}"

After that the scripts starts the preview server.

system("middleman server -p #{port}")


Using this script makes it easier to run middleman on your local machine: There won’t be any collisions between different middleman-servers or any other service when you start the preview server – this functionality has been added to middleman server in 3.4. But the script also makes sure that the same port is always re-used without any action by the user – even on different systems. There’s no need to add the port configuration to your config.rb. Furthermore you don’t have to remember the URL to open the landing page of your middleman-site in your browser.

Hope you find this little script helpful. Thanks for reading.


If you found a mistake in this article or would like to contribute some content to it, please file an issue in this Git Repository


The contents of this article are put together to the best of the authors' knowledge, but it cannot be guaranteed that it's always accurate in any environment. It is up to the reader to make sure that all information found in this article, does not do any damage to the reader's working environment or wherever this information is applied to. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, arising from, out of or in connection with this article. Please also note the information given on the Licences' page.