正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

CI/CDキャッシュの例

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

ジョブの実行時に毎回依存関係とビルドアーティファクトをダウンロードしなくても済むように、キャッシュを使用してください。キャッシュを使用すると、以前にダウンロードしたコンテンツが再利用されるため、CI/CDパイプラインが高速化されます。

その他の例については、GitLab CI/CD templatesを参照してください。

キャッシュの戦略

これらの例では、ジョブとブランチ間でキャッシュを共有するためのさまざまな方法を示します。

同じブランチ内のジョブ間でキャッシュを共有する

各ブランチのジョブで同じキャッシュを使用するには、key: $CI_COMMIT_REF_SLUGを使用してキャッシュを定義します。

cache:
  key: $CI_COMMIT_REF_SLUG

この設定により、キャッシュを誤って上書きすることを防ぐことができます。ただし、マージリクエストの最初のパイプラインは遅くなります。次回コミットがブランチにプッシュされると、キャッシュが再利用され、ジョブがより速く実行されます。

次のコマンドで、ジョブごとおよびブランチごとにキャッシュを有効にできます。

cache:
  key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"

次のコマンドで、ステージごとおよびブランチごとにキャッシュを有効にできます。

cache:
  key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"

異なるブランチのジョブ間でキャッシュを共有する

すべてのブランチとすべてのジョブでキャッシュを共有するには、すべてに同じキーを使用します。

cache:
  key: one-key-to-rule-them-all

ブランチ間でキャッシュを共有しつつ、ジョブごとにキャッシュが一意になるようにするには、次のようにします。

cache:
  key: $CI_JOB_NAME

変数を使用してジョブのキャッシュポリシーを制御する

プルポリシーだけが異なるジョブの重複を減らすには、CI/CD変数を使用します。

例:

conditional-policy:
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      variables:
        POLICY: pull-push
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
      variables:
        POLICY: pull
  stage: build
  cache:
    key: gems
    policy: $POLICY
    paths:
      - vendor/bundle
  script:
    - echo "This job pulls and pushes the cache depending on the branch"
    - echo "Downloading dependencies..."

この例では、ジョブのキャッシュポリシーは次のとおりです。

  • デフォルトブランチへの変更の場合: pull-push
  • 他のブランチへの変更の場合: pull

キャッシュの依存関係

これらの例では、一般的な依存関係をプログラミング言語別にキャッシュする方法を示します。

Node.js

プロジェクトでnpmを使用してNode.jsの依存関係をインストールする場合、次の例では、すべてのジョブがそれを継承するようにデフォルトのcacheを定義します。デフォルトでは、npmはホームフォルダー(~/.npm)にキャッシュデータを保存します。ただし、プロジェクトディレクトリの外にあるものをキャッシュすることはできません。代わりに、./.npmを使用するようにnpmに指示し、次のように、ブランチごとにキャッシュします。

default:
  image: node:latest
  cache:  # Cache modules in between jobs
    key: $CI_COMMIT_REF_SLUG
    paths:
      - .npm/
  before_script:
    - npm ci --cache .npm --prefer-offline

test_async:
  script:
    - node ./specs/start.js ./specs/async.spec.js

ロックファイルからキャッシュキーを計算する

cache:key:filesを使用して、package-lock.jsonyarn.lockなどのロックファイルからキャッシュキーを計算し、多くのジョブで再利用できます。

default:
  cache:  # Cache modules using lock file
    key:
      files:
        - package-lock.json
    paths:
      - .npm/

オフラインミラーでのYarn

Yarnを使用している場合は、yarn-offline-mirrorを使用して、zip形式のnode_modules tarballをキャッシュできます。圧縮する必要のあるファイルが少ないため、キャッシュの生成がより迅速になります。

job:
  script:
    - echo 'yarn-offline-mirror ".yarn-cache/"' >> .yarnrc
    - echo 'yarn-offline-mirror-pruning true' >> .yarnrc
    - yarn install --frozen-lockfile --no-progress
  cache:
    key:
      files:
        - yarn.lock
    paths:
      - .yarn-cache/

PHP

プロジェクトでComposerを使用してPHPの依存関係をインストールする場合、次の例では、デフォルトのcacheを定義し、すべてのジョブがその依存関係を継承するようにします。PHPライブラリモジュールはvendor/にインストールされ、ブランチごとにキャッシュされます。

default:
  image: php:latest
  cache:  # Cache libraries in between jobs
    key: $CI_COMMIT_REF_SLUG
    paths:
      - vendor/
  before_script:
    # Install and run Composer
    - curl --show-error --silent "https://getcomposer.org/installer" | php
    - php composer.phar install

test:
  script:
    - vendor/bin/phpunit --configuration phpunit.xml --coverage-text --colors=never

Python

プロジェクトでpipを使用してPythonの依存関係をインストールする場合、次の例では、デフォルトのcacheを定義し、すべてのジョブがその依存関係を継承するようにします。pipのキャッシュは.cache/pip/の下に定義され、ブランチごとにキャッシュされます。

default:
  image: python:latest
  cache:                      # Pip's cache doesn't store the python packages
    paths:                    # https://pip.pypa.io/en/stable/topics/caching/
      - .cache/pip
  before_script:
    - python -V               # Print out python version for debugging
    - pip install virtualenv
    - virtualenv venv
    - source venv/bin/activate

variables:  # Change pip's cache directory to be inside the project directory because GitLab can only cache local items.
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"

test:
  script:
    - python setup.py test
    - pip install ruff
    - ruff --format=gitlab .

Ruby

プロジェクトでBundlerを使用してgemの依存関係をインストールする場合、次の例では、デフォルトのcacheを定義し、すべてのジョブがその依存関係を継承するようにします。gemはvendor/ruby/にインストールされ、ブランチごとにキャッシュされます。

default:
  image: ruby:latest
  cache:                                            # Cache gems in between builds
    key: $CI_COMMIT_REF_SLUG
    paths:
      - vendor/ruby
  before_script:
    - ruby -v                                       # Print out ruby version for debugging
    - bundle config set --local path 'vendor/ruby'  # The location to install the specified gems to
    - bundle install -j $(nproc)                    # Install dependencies into ./vendor/ruby

rspec:
  script:
    - rspec spec

異なるgemを必要とするジョブがある場合は、グローバルなcache定義でprefixキーワードを使用します。この設定により、ジョブごとに異なるキャッシュが生成されます。

たとえば、テストジョブでは、本番環境にデプロイするジョブと同じgemが必要ない場合があります。

default:
  cache:
    key:
      files:
        - Gemfile.lock
      prefix: $CI_JOB_NAME
    paths:
      - vendor/ruby

test_job:
  stage: test
  before_script:
    - bundle config set --local path 'vendor/ruby'
    - bundle install --without production
  script:
    - bundle exec rspec

deploy_job:
  stage: production
  before_script:
    - bundle config set --local path 'vendor/ruby'   # The location to install the specified gems to
    - bundle install --without test
  script:
    - bundle exec deploy

Go

プロジェクトでGoモジュールを使用してGoの依存関係をインストールする場合、次の例では、すべてのジョブが拡張できるgo-cacheテンプレートでcacheを定義します。Goモジュールは${GOPATH}/pkg/mod/にインストールされ、goプロジェクトのすべてに対してキャッシュされます。

.go-cache:
  variables:
    GOPATH: $CI_PROJECT_DIR/.go
  before_script:
    - mkdir -p .go
  cache:
    paths:
      - .go/pkg/mod/

test:
  image: golang:latest
  extends: .go-cache
  script:
    - go test ./... -v -short

ビルドアーティファクトとダウンロードをキャッシュする

これらの例では、コンパイルされたオブジェクトとダウンロードされたファイルをキャッシュして、ビルドを高速化する方法を示します。

Ccacheを使用してC/C++コンパイルをキャッシュする

C/C++プロジェクトをコンパイルする場合、Ccacheを使用してビルド時間を短縮できます。Ccacheは、以前のコンパイルをキャッシュし、同じコンパイルがいつ再度実行されるかを検出することで、再コンパイルをスピードアップします。Linuxカーネルのような大規模なプロジェクトをビルドするときに、コンパイルが大幅にスピードアップすることが期待できます。

cacheを使用して、作成されたキャッシュをジョブ間で再利用します。次に例を示します。

job:
  cache:
    paths:
      - ccache
  before_script:
    - export PATH="/usr/lib/ccache:$PATH"  # Override compiler path with ccache (this example is for Debian)
    - export CCACHE_DIR="${CI_PROJECT_DIR}/ccache"
    - export CCACHE_BASEDIR="${CI_PROJECT_DIR}"
    - export CCACHE_COMPILERCHECK=content  # Compiler mtime might change in the container, use checksums instead
  script:
    - ccache --zero-stats || true
    - time make                            # Actually build your code while measuring time and cache efficiency.
    - ccache --show-stats || true

単一のリポジトリに複数のプロジェクトがある場合、各プロジェクトに個別のCCACHE_BASEDIRは必要ありません。

cURLでダウンロードをキャッシュする

プロジェクトでcURLを使用して依存関係またはファイルをダウンロードする場合、ダウンロードしたコンテンツをキャッシュすることができます。新しいダウンロードが利用可能になると、ファイルは自動的に更新されます。

job:
  script:
    - curl --remote-time --time-cond .curl-cache/caching.md --output .curl-cache/caching.md "https://docs.gitlab.com/ci/caching/"
  cache:
    paths:
      - .curl-cache/

この例の場合、cURLはWebサーバーからファイルをダウンロードし、.curl-cache/のローカルファイルに保存します。--remote-timeフラグはサーバーからレポートされた最終変更時刻を保存し、cURLは--time-condを使うことにより、その最終変更時刻を、キャッシュされたファイルのタイムスタンプと比較します。リモートファイルのタイムスタンプのほうが新しい場合、ローカルキャッシュは自動的に更新されます。