小ネタで恐縮です。HerokuにRailsアプリをデプロイする場合やRubyバージョンをアップグレードする場合、Bundlerのバージョンで罠を踏まないためにどうしたらよいのかを自分用にまとめました。以下は2020年4月時点の情報です。
最近のBundlerとHerokuの事情
まず現状がどうなっているかをまとめました。
BundlerはRuby 2.6から組み込みになった
Bundlerは、元々追加でインストールするgemでした。かつてはRubyの新しいバージョンをインストールするとgem install bundler
を実行してからRailsなどで作業するというのが定番でした。
しかしその後、Ruby 2.6.0-preview3でBundler 1.17.1が組み込まれ、Ruby 2.6.0正式版ではBundler 1.17.2が組み込まれました。
Ruby 2.7ではBundler 2.1.2が組み込まれています。
バンドルに使ったBundlerのバージョンは、Gemfile.lockのBUNDLED WITH
に刻まれます。
ローカル環境で以下のように実行すれば他のバージョンのBundlerを追加インストールすることはできますが、組み込みのバージョンのBundlerは削除できません。
$ gem install bundler:1.17.3
Bundlerバージョンが複数共存するとややこしくなりそうなので、自分は避けています。
HerokuではBundlerのバージョンを指定できない
上のヘルプの冒頭に「Herokuで使われるBundlerのバージョンは変更できない」と記載されています。次を参照してください。
RubyとBundlerのバージョン
- 元記事: Heroku Ruby Support | Heroku Dev Center(2019/10/01の情報)
Herokuにデプロイすると、使うRubyのバージョンに応じて、自動的にBundlerのバージョンが以下のように決定されます。これは変えられません。
- Gemfile.lock末尾の
BUNDLED WITH
でBundler 2.xが指定されているアプリ - Bundler 2.0.2が使用される
- Gemfile.lock末尾の
BUNDLED WITH
でBundler 1.xが指定されているアプリ - Bundler 1.17.3が使用される
- Gemfile.lock末尾の
BUNDLED WITH
でBundlerのバージョンが指定されていないアプリ - Bundler 1.17.3が使用される
Gemfile.lockのBUNDLED WITH
は削除されるようになった
- 元記事: Ruby apps will now have the `BUNDLED WITH` declaration in their `Gemfile.lock` removed after detecting Bundler version | Heroku Dev Center(2019/12/06の情報)
現在のHerokuではエラー抑制のため、デプロイ時にBundlerのバージョンを検出した後で、Gemfile.lockのBUNDLED WITH
を削除するようになりました。
結局どうすればよいか
原則として、Rubyに組み込みのBundlerをそのまま使うことになります。
自分が一番気になったのは、ローカルでbundle install
したときのBundlerのバージョンと、Herokuで使われるBundlerのバージョンが違っていたらおかしなことになりはしないかというものでした。
しかし上にあるように、Gemfile.lockのBUNDLED WITH
はHeroku側で削除されるので、ローカルで使ったBundlerのバージョンに関係なく、Heroku指定バージョンのBundlerが使われます。
つまりローカルで使うBundlerのバージョンは基本的に何でもよい(は言い過ぎですが)ということになります。
実際、ローカル開発環境のBundlerが2.1.4(Ruby 2.7に組み込み)のRailsアプリをHerokuにデプロイすると、上の表のとおり、Heroku側ではBundler 2.0.2が使われ、Railsアプリは問題なく動作しました。
もちろんBundlerのバージョンがローカルとHerokuで微妙に変わることで何か起きる可能性はなきにしもあらずですし、今後変わる可能性もありますが、基本的にこうすることにしました。
古いBundlerを使いたい場合
アプリのRubyが2.6より古い場合などはそうもいかないかもしれません。
以下のヘルプには「もっと古いバージョンのBundlerを使う場合の方法」も記載されていますが、あくまで一時的なものであって将来にわたって保証されるわけではないと断り書きがあります。古いBundlerを無理やり使うよりは、新しいBundlerに乗り換える方が後々無難かと思いました。
おまけ
DockerでHerokuにRailsをデプロイできる
まだ試していませんが、最近のHerokuではDockerでRailsをデプロイできます。
最近のBundler
将来Bundler 3.0でbreaking changesが入ることがこのスライドで予告されています。
関連記事
ちょっと待った! Railsでgitリポジトリから除外すべきでないファイル:Gemfile.lockとdb/schema.rb