【入門編】CI/CDスピードアップ術:CircleCIのキャッシュ戦略でビルド時間を劇的に短縮する – バージョン管理・CI/CD活用バイブル

こんにちは!開発チームの背中を押す先輩エンジニアです。

毎日の開発作業、お疲れ様です。
「機能を作って、さあプッシュ!……あれ、まだビルドが終わらないな」
CI/CDのビルド待ち時間、地味にストレスが溜まりますよね。コーヒーブレイクに行くには短すぎるし、かといって集中力を切らすには絶妙な長さ。この「待ち時間」の積み重ねが、チーム全体の開発者体験(DX)をじわじわと蝕んでいきます。

でも、安心してください。CircleCIの「キャッシュ戦略」を正しく理解し、設定をひと工夫するだけで、この待ち時間は劇的に短縮できます。

今回は、初心者の方でも迷わず実装できるように、CircleCIのキャッシュの仕組みから、Node.js(npm)やRuby(Bundler)の依存関係を爆速でキャッシュする実践的なテクニックまで、優しく論理的に解説していきます。

これをマスターすれば、あなたのチームの毎日の開発が劇的に快適になりますよ!

—

1. CircleCIのキャッシュってそもそも何?

CI/CDパイプラインが動くとき、裏側では毎回まっさらな仮想環境(コンテナ)が立ち上がります。
そのため、何もしない状態だと、以下のようなムダな作業を毎回のビルドで行うことになります。

1. 空っぽの環境が起動する
2. インターネットの海から、何百・何千もの重いライブラリ(`node_modules`や`vendor/bundle`など)を毎回ゼロからダウンロードする
3. やっとテストが走り始める

これでは時間がかかるのも当然です。

キャッシュとは、前回のビルドで作った「重いファイルたち(依存関係)」をどこかに保存しておき、次回のビルドで「再利用」する仕組みです。毎回海まで水を汲みに行くのではなく、家のすぐ横に貯水タンクを置いておくようなイメージですね。

—

2. 登場人物は2つだけ:`restore_cache` と `save_cache`

CircleCIでキャッシュを扱うために覚えるべき命令(ステップ)は、基本的にたったの2つです。

  • `restore_cache`: 過去に保存したキャッシュを、環境に戻す(復元する)
  • `save_cache`: 新しくダウンロードした依存関係を、次のために保存する

これらを設定ファイル(`.circleci/config.yml`)に組み込んでいきます。

—

3. 実践!Node.js (npm) の依存関係を爆速キャッシュする

まずは、モダンなWeb開発で最もよく使われるNode.js(npm)を例に見ていきましょう。

以下の設定ファイルを見てください。ポイントはコメントで丁寧に解説しています。

version: 2.1

共通で使用する環境や実行環境の定義
orbs:
node: circleci/node@5.1.0

jobs:
build:
docker:

  • image: cimg/node:18.16.0 # 安定したNode.jsの公式イメージ

steps:

  • checkout # GitHubからソースコードをクローン

# 1. キャッシュの復元

  • restore_cache:

keys:
# lockファイルのハッシュ値をキーにして、依存関係が変わったか判定する

  • v1-npm-deps-{{ checksum “package-lock.json” }}

# 万が一完全一致しない場合、過去のv1で始まるキャッシュをフォールバックとして使う

  • v1-npm-deps-

# 2. 依存関係のインストール

  • run:

name: Install Dependencies
command: npm ci

# 3. キャッシュの保存(もしロックファイルが変わっていれば新しく保存される)

  • save_cache:

key: v1-npm-deps-{{ checksum “package-lock.json” }}
paths:

  • ~/.npm # npmのキャッシュが保存されるディレクトリを指定

ここが重要:`checksum` の魔法

`key` の部分にある `{{ checksum “package-lock.json” }}` に注目してください。
CircleCIは、`package-lock.json`(ライブラリのバージョンが正確に記録されたファイル)の中身が変わったかどうかを自動で計算し、その結果をキーに含めます。

  • 依存関係が変わっていない場合: 保存されたキャッシュがそのまま使われる(爆速⚡️)
  • 新しくライブラリを追加・更新した場合: ハッシュ値が変わるため、古いキャッシュを無視して新しくインストールし、それが新しいキャッシュとして保存される(安全🔒)

人間が「キャッシュをクリアしなきゃ!」と意識する必要は一切ありません。システムが勝手に賢く判断してくれます。

—

4. Ruby (Bundler) の場合:実戦的なキャッシュ設定

Ruby on Railsなどのプロジェクトでも基本は同じです。Bundlerの場合は、`vendor/bundle`というディレクトリにGemをインストールすることが多いため、指定するパスが変わります。

version: 2.1

jobs:
build:
docker:

  • image: cimg/ruby:3.2.2

steps:

  • checkout

# キャッシュの復元

  • restore_cache:

keys:

  • v1-bundle-deps-{{ checksum “Gemfile.lock” }}
  • v1-bundle-deps-

# Bundlerのパスを設定してインストール

  • run:

name: Bundle Install
command: |
bundle config set –local path ‘vendor/bundle’
bundle install

# キャッシュの保存

  • save_cache:

key: v1-bundle-deps-{{ checksum “Gemfile.lock” }}
paths:

  • vendor/bundle

このように、「どのファイルを基準に判定するか(checksum)」と「どこを保存するか(paths)」の2つさえ間違わなければ、どんな言語やツールであっても簡単にキャッシュを導入できます。

—

5. キャッシュ戦略を成功させるためのプロの知見(ハック)

最後に、現場で数々のパイプラインを最適化してきた私から、少し踏み込んだ「知見」をシェアします。

① キャッシュのサイズを大きくしすぎない

「あれもこれも」とプロジェクト全体やビルド成果物(`dist`や`build`フォルダなど)までキャッシュしようとすると、キャッシュのアップロード・ダウンロード自体に時間がかかるようになり、本末転倒になります。
キャッシュの対象は「外部からダウンロードする重い依存関係(`node_modules`, `vendor/bundle`など)」に絞るのが鉄則です。

② キャッシュキーのプレフィックス(`v1-`など)をうまく使う

設定例で `v1-npm-deps-…` のように `v1` というプレフィックスをつけていました。
もし「Node.jsのバージョンを大きく上げた」「キャッシュの構造をごっそり変えたい」という時は、ここを `v2-` に書き換えるだけで、古いゴミキャッシュを一掃し、綺麗な状態からスタートできます。トラブルシューティングの強力な武器になります。

—

まとめ:待ち時間を削り、開発のフロー状態(ゾーン)を守ろう

今回は、CircleCIの `restore_cache` と `save_cache` を使ったビルド時間短縮のテクニックを解説しました。

  • キャッシュとは、前回の依存関係を再利用してムダなダウンロードを省く仕組み
  • `checksum` を使って、ファイルの変更を検知しながら賢く管理する
  • 対象は「外部の依存関係」に絞ることで、最大の効果を発揮する

たった数行の設定を加えるだけで、ビルド時間が半分以下になることも珍しくありません。浮いた時間は、新しいコードを書くため、あるいは美味しいコーヒーをゆっくり楽しむために使いましょう。

あなたのチームの開発者体験が、今日より少しでも良くなることを心から応援しています!

タイトルとURLをコピーしました