Bundler vs RubyGems: CI で Ruby の依存関係はどう機能するか
これらは実際にはライバルではありません。RubyGems は gem を install し、Bundler はそれらを固定して解決します。そして CI ではほぼ常に Bundler を上に載せたいはずです。
RubyGems は Ruby のパッケージマネージャであり registry クライアントです(gem install)。Bundler はその上に載り、Gemfile から一貫した gem の集合を解決し、再現可能な install のために Gemfile.lock に固定します。
| RubyGems | Bundler | |
|---|---|---|
| 役割 | 個々の gem を install | 依存関係の集合を解決 + ロック |
| Lockfile | なし | Gemfile.lock |
| 再現可能な install | 手動で固定した場合のみ | あり (lock から) |
| CI コマンド | gem install <gem> | bundle install / bundle ci |
| 関係 | 基盤となる層 | RubyGems の上に構築 |
CI において
アプリケーションでは Bundler を使いたいはずです。Gemfile.lock を commit し、bundle install(--deployment / frozen 設定つき)を実行して、すべてのパイプラインが同一の gem バージョンを得るようにします。素の gem install は job 内でスタンドアロンな CLI ツールを install するには問題ありませんが、再現可能なプロジェクト環境は得られません。Bundler は内部で RubyGems を使っており、競合するのではなく協調します。
gem を cache する
vendor/bundle(または gem)ディレクトリを Gemfile.lock でキーづけして cache し、bundle path を設定して install が再取得ではなく復元されるようにします。どの Ruby バージョンを対象にしても install は CI runner 上で実行され、ネイティブ gem のコンパイルが支配的な場合はより高速なマネージド runner が役立ちます。
Decide with your own numbers, not a feature table
Feature comparisons age badly and rarely decide anything, because both tools in a mature category can do the job. What differs is how each behaves on your repository, and that takes one afternoon to measure.
# time a cold install with each candidate, cache cleared
hyperfine --prepare "rm -rf node_modules" --warmup 1 \
"<tool-a> install" "<tool-b> install"
# and the thing CI actually pays for: a cold run with no local cache
docker run --rm -v "$(pwd):/w" -w /w node:22 sh -c "<tool> install"What actually changes when you switch
- Lockfile format. A switch is a one-way door for anyone still on the old tool until everyone migrates, so plan it as a single coordinated change.
- Resolution strictness. Tools differ on whether an undeclared transitive import works, and the stricter one will surface latent bugs as new failures.
- CI cache configuration. The cache path and key differ per tool; carrying over the old ones silently disables caching.
- Everyone on the team and every runner must move together. Pin the version so they cannot drift.
結論
Ruby アプリを構築するなら、再現可能な install のために commit した Gemfile.lock とともに Bundler を使ってください。job 内でスタンドアロンなツールが必要なだけなら gem install で十分です。これらは層であって代替ではありません。Bundler がプロジェクトにとって正しいデフォルトです。