bundle install が rubygems 往復 と Git 源の複製 の二系統に分岐すると、国境越え RTT と 接続プール枯渇 でフラップしやすくなります。本稿は BUNDLE_JOBS/BUNDLE_RETRY、ミラー連鎖、vendor/cache と CI キャッシュ鍵、Gemfile.lock 検収 を一枚の判断表に落とします。ホーム・技術ブログ一覧・購入・ヘルプはログイン不要です。関連:Composer/Packagist マトリクス、Gradle・Maven CI キャッシュ、Git・npm・brew ミラー最適化。
シナリオとボトルネック(二系統取得・タイムアウト・ロック一貫性)
.gem 取得と git: 源は 律速が別 です。前者は HTTP 並列とミラー、後者は clone と認証。同一出口で BUNDLE_JOBS×パイプライン並列 が NAT 上限 を超えるとタイムアウトが断続します。
Gemfile.lock はコミット単位の契約。Bundler 版・PLATFORMS・意図しない update が混ざると 同じ SHA でも CI だけ解決が変わります。まず系統を切り分けてから数値を当てます。
- 判断①:遅いのは
Fetching gem metadataかFetching source indexか。前者は rubygems/ミラー、後者は インデックス鮮度 or プロキシ を疑う。 - 判断②:ログに
Git errorが多いなら git 源を優先 してGIT_TERMINAL_PROMPT=0・浅複製・トークン形式を固定する。 - 判断③:
bundle install後に lock が汚れるならbundle lock --checkを マージ必須ゲート に入れる。
並列と接続プール:BUNDLE_JOBS・BUNDLE_RETRY・失敗再試行しきい値
BUNDLE_JOBS は 1 回の install 内 の並列。帯域と相手の接続制限 が先に効くことが多いです。BUNDLE_RETRY は揺らぎへの再試行。CI の retry: と併用するなら timeout と整合させます。
| Runner 想定 | BUNDLE_JOBS 初期値 | BUNDLE_RETRY | CI retry 回数(目安) | 指数バックオフ上限(目安) |
|---|---|---|---|---|
| 4 vCPU・単一パイプライン | 3〜4 | 3 | 0〜1 | 8〜16 秒×3 回 |
| 8 vCPU・帯域余裕 | 6〜8 | 3 | 1 | 同上 |
| 同一出口に並列パイプライン 3+ | 過大(例 16) | 3 | パイプライン側を 1〜2 に制限 | 16〜32 秒まで延長可 |
| git 源が主(大規模 monorepo) | 2〜4 | 3 | 1〜2 | clone 失敗はジョブ単位で再実行 |
export BUNDLE_JOBS=4
export BUNDLE_RETRY=3
export GIT_TERMINAL_PROMPT=0
# 例: GitHub HTTPS(トークンは CI シークレットへ。実際の変数名に合わせて置換)
export BUNDLE_GIT__GITHUB__COM="x-access-token:${GITHUB_TOKEN}"
bundle config set --local deployment 'true'
bundle config set --local path 'vendor/bundle'
bundle lock --check
bundle install --jobs "${BUNDLE_JOBS}" --retry "${BUNDLE_RETRY}"
国境越えミラーと Git 源戦略(rubygems・社内・GitHub)
国境越えでは ミラー or 社内キャッシュ が本体になりがちです。bundle config set mirror.https://rubygems.org … で取得元を固定し、障害時の切替 を Runbook に残します。
| 経路 | 設定の核 | 向くチーム | 注意 |
|---|---|---|---|
| 本家 rubygems | 既定のまま | Runner が近接リージョン | 429/帯域で不安なら下の行へ |
| 地域/企業ミラー | mirror.https://rubygems.org | 跨境メイン | インデックス遅延で checksum 問題が出たら鮮度調査 |
| GitHub HTTPS | BUNDLE_GIT__GITHUB__COM または netrc | private fork/org gem | トークン期限・スコープ・IP 許可 |
| Git SSH | GIT_SSH_COMMAND・known_hosts | deploy key 運用 | 並列 clone で ssh-agent 競合に注意 |
bundle config set --global mirror.https://rubygems.org https://gems.example.com
# 浅複製で git gem の転送量を抑える(リポジトリポリシーに合わせる)
export GIT_DEPTH=1
git config --global fetch.depth 1
bundle install --jobs 4 --retry 3
Gemfile.lock のドリフトと vendor/cache・CI キャッシュ鍵
キャッシュキーは Gemfile.lock ハッシュ+Ruby 版 を必須に。vendor/bundle か vendor/cache 同梱かは リポサイズと監査 のトレードオフで決めます。
| 方式 | 正とするディレクトリ | CI キャッシュキーに含めるもの | メモ |
|---|---|---|---|
| vendor/bundle のみ | vendor/bundle | hashFiles('Gemfile.lock') + Ruby + Bundler | シンプル。複数ジョブで共有する場合はファイルロック競合に注意 |
| package 同梱 | vendor/cache + lock | lock + vendor/cache の指紋 | 外向き不安定環境で強い |
| Bundler グローバルキャッシュ | $BUNDLE_USER_HOME 配下 | lock + bundler 版 | ディスク掃除ポリシーが別途必要 |
ruby -vと CI のセットアップが パッチレベルまで 揃っている。Gemfile.lockのPLATFORMSに CI のプラットフォーム が含まれる(必要ならbundle lock --add-platform)。BUNDLED WITHと CI のbundle -vが一致、またはgem install bundler -vで揃えた。bundle lock --checkが緑。bundle install --deployment(または--frozen)で 勝手な更新が無い。vendor/cacheを使う場合、不足 .gem が無い ことをbundle install --local --deploymentで確認済み。
# 検収(ローカル/CI いずれも) bundle lock --check bundle install --deployment --jobs 4 --retry 3 # オフライン寄せの更新フロー例 bundle package --all # vendor/cache をコミット後、CI では bundle install --local --deployment --jobs 4 --retry 3
FAQ
BUNDLE_JOBS を上げても速くならない
git 源や TLS の遅延が支配的な可能性があります。4 前後へ下げ、ミラー命中と浅複製を先に直し、ログでどの URL が律速かを切り分けます。
CI だけ Gemfile.lock が変わる
プラットフォーム行と Bundler 版の差が典型です。開発機で lock を再生成してコミットする運用にし、CI で bundle update を暗黙に走らせないようにします。
git 源 gem が認証で落ちる
BUNDLE_GIT__*__COM のホストエスケープ、トークン期限、SSH の known_hosts を確認し、HTTPS と SSH を混在させない運用が安全です。