35歳からの中二病エンジニア

社寺・鉄道・アニメを愛でるウェブ技術者の呟き

Rails 7.1の切り戻しとALBのヘルスチェックで板挟みになった話

最近複数のプロダクトでRails 7.1への移行を行っているが、その中でRails 7.0へ切り戻しが必要になって苦労した事例があったので共有しておこうと思う。

キャッシュフォーマットの互換性について

Rails 7.1 から、キャッシュに値を保存するときのシリアライズフォーマットに新しいバージョンが追加された。Rails 7.1 は古いバージョンのキャッシュを読み取ることが可能だが、Rails 7.1 で保存されたキャッシュをRails 7.0が読み取ることはできない。

詳しくはRailsガイドの6.1から7.0へのアップグレードガイドを参照されたい(7.0から7.1へのガイドには記述が無いが、内容は概ね同様である)。

railsguides.jp

実際、Rails 7.0に切り戻した所、以下のようなエラーが発生した。

TypeError incompatible marshal file format (can't be read) format version 4.8 required; 17.1 given

ALBのヘルスチェックについて

さて、今回切り戻しで問題が発生したのは、ECSのステージング環境である。ここでRails 7.0への切り戻しをデプロイしようとした所、コンテナが立ち上がっては落とされるありがちなエラーが発生した。確認した所、ALBのヘルスチェックに失敗しているということだった。

このサービスでは、ヘルスチェックのパスを / に設定していたため、Railsのルートを参照して上記エラーで落ちていたということだ。Rails 7.1にすると問題があって、切り戻しすると今度はキャッシュの非互換で落ちるという板挟みになってしまった。

今回はこの問題を解消するために、ヘルスチェックのパスを /healthcheck.html という静的ファイルに変更して乗り切ることにした。そもそも、このサービスではRailsのルートに対してDatadogで死活監視をしているので、ALB側のヘルスチェックでも行う必要は無いと判断したからだ。ただ、もし同様の事例で死活監視を他で行っていない場合は、静的ファイルだとRails側のエラーに気付けない場合があるので注意が必要だ。

おわりに

今までステージング以上の環境でRailsを切り戻すということが無かったのでこうした非互換問題とは無縁だったが、実際遭遇してみたらヘルスチェックとも絡んでちょっと面倒な事態になってしまった。Rails 7系へのアップデートの際の参考になれば幸いである。