AppEngineのRuby3.2からの変更点

AppEngineで稼働中のRailsアプリケーションのRubyバージョンを3.1から3.2に上げたところデプロイに失敗した。
ERROR: (gcloud.app.deploy) Error Response: [14] Cloud Container build either failed or interrupted.

Ruby 3.1までは、ビルド環境に専用のDockerコンテナが使われていたが、Ruby 3.2からはbuildpacksを使うようになったとのこと。
app.yml に以下を設定する必要がある。
runtime_config:
operating_system: "ubuntu22"

次に以下のエラーが出力された。
Failure: (ID: 1bb9c1ca) There is a conflict between the Ruby version “3.2.2” in Gemfile.lock and “3.2.2\n” in .ruby-version file.Please resolve the conflict by choosing only one way to specify the ruby version.
.ruby-version
の末尾の改行も文字列として拾ってしまっているようだった。改行を取り除くことでエラーが解消した。

任意のコマンドが実行できなくなってしまった。
Railsアプリケーションのtaskを実行するため、これまではインスタンスにsshで接続して、コンテナに対して任意のコマンドを実行していたが、buildpacksによりコンテナが作られるようになって、これができなくなっていた。

buildpacksとは、Dockerfileなど宣言的な定義ファイルを使うことなく、アプリケーションの実行イメージを作るビルドツール。例えば、Gemfile.lockというファイルが見つかれば、そのファイルからRubyのバージョンを特定して、railsというgemが見つかれば起動コマンドを rails server -p $PORT
にするという具合(イメージです。)

buildpacksは最終的に実行対象を /cnb/process/web
という単一ファイルにまとめる。もともと想定されていないコマンドは実行できないということになる。

Google Cloudで使われているbuildpabks。
ビルド部分にはBazelというツールが使われている。
最終的に /cnb/process/web
をエントリーポイントにしていることが分かる。
https://github.com/GoogleCloudPlatform/buildpacks/blob/659b4c74c371208da3361a59cdaa871830e98848/builders/ruby/acceptance/config.yaml

カスタムランタイムにするしかないのかな。