Posted at

環境変数を用いて手間なく Rails をメンテナンスモード (HTTP 503) に切り替える

More than 1 year has passed since last update.

サイトメンテナンス時には HTTP 503 Service Unavailable を返すようにするのが SEO の観点から好ましいです。

設定を行う箇所として、ロードバランサ、Rails アプリ、Web サーバなど色々な選択肢が考えられますが、今回は「環境変数のみを用いて設定変更を可能にする方法」を説明します。


背景

「新機能デプロイ時、メンテナンスモードに切り替えたいんだけど、そんな手間のかかることはしたくなくて、社内の IP から以外は全部 503 返したいだけなんだよなー。あと、アプリエンジニアだけで完結させたいなー」


メリット

システム構成次第なところもありますが、環境変数 の変更はロードバランサ、Rails アプリ、Web サーバの設定変更に比べ、非常に手間が少ないです。

例えば、AWS OpsWorks ではブラウザ上から簡単に環境変数の変更、デプロイによる反映が行なえ、ものの数ステップでメンテナンスモードへの移行が完了します。

また、この機能を実現するために必要な Rails の設定も非常に簡素な点もメリットです。

「そんな大掛かりなことしたくなくて、一定期間 503 が返れば良いんだけど……」というケースに最適だと思います。


デメリット

以下に実現できることとして書きますが、実現方法も切替時の設定方法も非常にシンプルなため、機能自体もシンプルです。

Rails アプリ側でもっと複雑な制御がしたいんだけど……というケースであれば biola/turnout のような gem を利用するのが良いかもしれません。


実現できること


  • 環境変数を用いて以下の設定が可能


    • メンテナンスモードの ON/OFF

    • IP アドレスによるホワイトリストの指定




実現方法

以下の設定を app/controllers/application_controller.rb に追加するだけで完了です。

class ApplicationController < ActionController::Base

before_action :render_503_except_for_whitelisted_ips, if: :maintenance_mode?

def maintenance_mode?
ENV["MAINTENANCE_MODE"] == "true"
end

def render_503_except_for_whitelisted_ips
ips_in_whitelist = (ENV["ALLOWED_IPS"] || "").split(",")
return if ips_in_whitelist.include?(request.remote_ip)

render(
file: Rails.public_path.join("503.html"),
content_type: "text/html",
layout: false,
status: :service_unavailable,
)
end
end

また、ここでは public/503.html を読み込むようにしていますので、必要に応じて変更してください。


利用方法

以下の環境変数を設定し、それを反映するだけです。

キー

MAINTENANCE_MODE
"true" を設定するとメンテナンスモードへ移行します

ALLOWED_IPS
アクセスを許可したい IP アドレスをカンマ区切りで指定します

rails server を使った例だと、以下のようになります。

$ MAINTENANCE_MODE=true ALLOWED_IPS=192.168.145.2,192.168.145.3 bin/rails s -b 0.0.0.0

以上、とっても簡単!


まとめ

環境変数を利用すると楽ちん!


リンク