Codenoble

Creating quality websites and web applications

Simple Rails Maintenance Mode

Adam Crownoble

As I write this, I'm sitting at home in the dark. Sweat beads forming on my forehead as the 90° weather outside suddenly discovers there's no air conditioning to keep it at bay. Yes, I am the victim of a power outage. An all too present reminder that downtime happens.

Downtime is an unfortunate reality of working in IT. Whether it's planned or not, even the likes of Amazon and Google can't be up 100% of the time and neither can you.

When downtime does happen it pays to be ready with a quick response. When faced with a planned downtime a few years ago I searched the internet for a solution for our Ruby applications. Most of the solutions I found involved complex and inflexible web server configurations combined with custom deployment scripts that I wasn't too eager to jump into. So I set out to write a Rack middleware based Ruby gem to make my and other's downtime a little less painful.

The end result is called Turnout. It's one of my more popular open source gems, so I thought it deserved a blog post of it's own.

Getting Started

Installing Turnout is easy. Add gem 'turnout' to your Gemfile and you're done.

To start and stop maintenance mode just run bundle exec rake maintenance:start and bundle exec rake maintenance:end.

Customizing the Maintenance Page

By default Turnout will show a simple page with a 503 status that says "The site is temporarily down for maintenance. Please check back soon." Of course you can easily change this message or even the whole page if you like.

  • To provide a quick reason for your downtime just run bundle exec rake maintenance:start reason="Oopsie :(".
  • To create your own downtime page just create your own public/maintenance.html or public/maintenance.json (for APIs) in your project. If you'd like to have a customizable reason for your maintenance page just add {{ reason }} in the appropriate place.

Customizing Who Sees the Maintenance Page

The maintenance page is triggered by the presence of a file called maintenance.yml in your project's ./tmp directory. You can make changes to this file directly or through arguments passed to the rake maintenance:start task. The file is read on every request so you can make changes to it without having to restart your application, which can be a bad idea during a maintenance window.

  • To allow certain IP addresses, like your own, to bypass the maintenance page just set allowed_ips.
  • If only certain areas of your application are affected by the downtime you can allow certain paths through with the .allowed_paths setting.

Caveats

One final word of warning. Turnout injects itself into your application as Rack middleware. So the one condition for Turnout to work is that your application has to be able to at least start up. Things like upgrading Ruby or database downtime (especially with Active Record) can cause problems with your application's startup process, which means Turnout won't even have a chance to run.

For more details and tips be sure to check out Turnout's README on GitHub.

TL;DR: Put gem 'turnout' in your Gemfile and run rake maintenance:start/rake maintenance:end for quick and easy maintenance mode for Rack applications.

ruby rails rack middleware