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

GitLab CI/CDでのキャッシュ

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

キャッシュとは、ジョブがダウンロードして保存する1つ以上のファイルのことです。同じキャッシュを使用する後続のジョブは、ファイルを再度ダウンロードする必要がないため、より高速に実行されます。

.gitlab-ci.ymlファイルでキャッシュを定義する方法については、cacheのリファレンスを参照してください。

高度なキャッシュキー戦略については、以下を使用できます:

  • cache:key:files: 特定のファイルの内容にリンクされたキーを生成します。
  • cache:key:files_commits: 特定のファイルの最新のコミットにリンクされたキーを生成します。

キャッシュとアーティファクトの違い

インターネットからダウンロードしたパッケージなどの依存関係にはキャッシュを使用します。キャッシュはGitLab Runnerがインストールされている場所に保存され、分散キャッシュが有効になっている場合はS3にアップロードされます。

ステージ間で中間ビルドの結果を渡すには、アーティファクトを使用します。アーティファクトはジョブによって生成され、GitLabに保存され、ダウンロードが可能です。

アーティファクトとキャッシュはどちらも、プロジェクトディレクトリからの相対パスを定義します。また、外部のファイルにリンクすることはできません。

キャッシュ

  • cacheキーワードを使用して、ジョブごとにキャッシュを定義します。それ以外の場合は無効になります。
  • 後続のパイプラインでそのキャッシュを使用することができます。
  • 依存関係が同一である場合、同じパイプライン内の後続のジョブはキャッシュを使用できます。
  • 異なるプロジェクト間でキャッシュを共有することはできません。
  • デフォルトでは、保護ブランチと保護されていないブランチはキャッシュを共有しません。ただし、この動作を変更できます。

アーティファクト

  • ジョブごとにアーティファクトを定義します。
  • 同じパイプラインの後続のステージのジョブは、アーティファクトを使用できます。
  • アーティファクトは、デフォルトで30日後に有効期限が切れます。カスタムの有効期限を定義できます。
  • 最新のアーティファクトを保持する設定が有効になっている場合、最新のアーティファクトは有効期限切れになりません。
  • 依存関係を使用して、アーティファクトをフェッチするジョブを制御します。

キャッシュに関する優れたプラクティス

キャッシュの可用性を最大限に高めるには、次の1つ以上を行います:

Runnerがキャッシュと効率的に連携できるようにするには、次のいずれかを実行する必要があります:

  • すべてのジョブに単一のRunnerを使用する。
  • 分散キャッシュを持つ複数のRunnerを使用する。この場合、キャッシュはS3バケットに保存されます。GitLab.comのインスタンスRunnerは、この方法で動作します。これらのRunnerはオートスケールモードにできますが、そうである必要はありません。キャッシュオブジェクトを管理するには、ライフサイクルルールを適用して、一定期間後にキャッシュオブジェクトを削除します。ライフサイクルルールは、オブジェクトストレージサーバーで利用できます。
  • 同じアーキテクチャを持つ複数のRunnerを使用し、これらのRunnerが共通のネットワークマウントされたディレクトリを共有してキャッシュを保存するようにする。このディレクトリは、NFSまたは同様のものを使用する必要があります。これらのRunnerはオートスケールモードである必要があります。

複数のキャッシュを使用する

1つのジョブにつき、最大4つのキャッシュを使用できます:

test-job:
  stage: build
  cache:
    - key:
        files:
          - Gemfile.lock
      paths:
        - vendor/ruby
    - key:
        files:
          - yarn.lock
      paths:
        - .yarn-cache/
  script:
    - bundle config set --local path 'vendor/ruby'
    - bundle install
    - yarn install --cache-folder .yarn-cache
    - echo Run tests...

複数のキャッシュがフォールバックキャッシュキーと組み合わされている場合、キャッシュが見つからないときは常にグローバルフ​​ォールバックキャッシュがフェッチされます。

フォールバックキャッシュキーを使用する

キャッシュごとのフォールバックキー

各キャッシュエントリは、fallback_keysキーワードで最大5つのフォールバックキーをサポートします。ジョブがキャッシュキーを見つけられない場合、ジョブは代わりにフォールバックキャッシュの取得を試みます。キャッシュが見つかるまで、フォールバックキーが順番に検索されます。キャッシュが見つからない場合、ジョブはキャッシュを使用せずに実行されます。次に例を示します:

test-job:
  stage: build
  cache:
    - key: cache-$CI_COMMIT_REF_SLUG
      fallback_keys:
        - cache-$CI_DEFAULT_BRANCH
        - cache-default
      paths:
        - vendor/ruby
  script:
    - bundle config set --local path 'vendor/ruby'
    - bundle install
    - echo Run tests...

この例では、次のようになります:

  1. ジョブはcache-$CI_COMMIT_REF_SLUGキャッシュを探します。
  2. cache-$CI_COMMIT_REF_SLUGが見つからない場合、ジョブはフォールバックオプションとしてcache-$CI_DEFAULT_BRANCHを探します。
  3. cache-$CI_DEFAULT_BRANCHも見つからない場合、ジョブは2番目のフォールバックオプションとしてcache-defaultを探します。
  4. いずれも見つからない場合、ジョブはキャッシュを使用せずにすべてのRuby依存関係をダウンロードしますが、ジョブが完了するとcache-$CI_COMMIT_REF_SLUGの新しいキャッシュを作成します。

フォールバックキーは、cache:keyと同じ処理ロジックに従います:

グローバルフ​​ォールバックキー

定義済み変数$CI_COMMIT_REF_SLUGを使用すれば、自分のcache:keyを指定できます。たとえば、$CI_COMMIT_REF_SLUGtestの場合、testでタグ付けされたキャッシュをダウンロードするようにジョブを設定できます。

このタグが付いたキャッシュが見つからない場合は、CACHE_FALLBACK_KEYを使用して、そのキャッシュが存在しない場合に使用するキャッシュを指定できます。

次の例では、$CI_COMMIT_REF_SLUGが見つからない場合、ジョブはCACHE_FALLBACK_KEY変数で定義されたキーを使用します:

variables:
  CACHE_FALLBACK_KEY: fallback-key

job1:
  script:
    - echo
  cache:
    key: "$CI_COMMIT_REF_SLUG"
    paths:
      - binaries/

キャッシュ抽出の順序は次のとおりです:

  1. cache:keyを取得試行する
  2. fallback_keysの各エントリを順番に取得試行する
  3. CACHE_FALLBACK_KEYのグローバルフ​​ォールバックキーを取得試行する

最初のキャッシュが正常に取得された後、キャッシュ抽出プロセスは停止します。

特定のジョブのキャッシュを無効にする

キャッシュをグローバルに定義すると、どのジョブも同じ定義を使用するようになります。ジョブごとにこの動作をオーバーライドできます。

ジョブに対してキャッシュを完全に無効にするには、次のように空のリストを使用します:

job:
  cache: []

グローバル設定を継承するが、ジョブごとに特定の設定をオーバーライドする

アンカーを使用すると、グローバルキャッシュを上書きせずにキャッシュ設定をオーバーライドできます。たとえば、1つのジョブのpolicyをオーバーライドする場合、次のようになります:

default:
  cache: &global_cache
    key: $CI_COMMIT_REF_SLUG
    paths:
      - node_modules/
      - public/
      - vendor/
    policy: pull-push

job:
  cache:
    # inherit all global cache settings
    <<: *global_cache
    # override the policy
    policy: pull

詳細については、cache: policyを参照してください。

キャッシュの一般的なユースケース

通常、キャッシュは、ジョブを実行するたびに依存関係やライブラリなどのコンテンツをダウンロードするのを防ぐために使用します。Node.jsパッケージ、PHPパッケージ、Ruby gem、Pythonライブラリなどをキャッシュできます。

例については、GitLab CI/CDテンプレートを参照してください。

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

各ブランチのジョブで同じキャッシュを使用するには、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-offline-mirrorを使用して、zip形式のnode_modulestarballをキャッシュできます。圧縮する必要のあるファイルが少ないため、キャッシュの生成がより迅速になります:

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/

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は必要ありません。

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

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を使うことにより、その最終変更時刻を、キャッシュされたファイルのタイムスタンプと比較します。リモートファイルのタイムスタンプのほうが新しい場合、ローカルキャッシュは自動的に更新されます。

キャッシュの可用性

キャッシュの目的は最適化ですが、常に機能することが保証されているわけではありません。場合によっては、キャッシュが必要な各ジョブでキャッシュされたファイルを再生成する必要があります。

.gitlab-ci.ymlでキャッシュを定義した後、キャッシュの可用性は次の要素に左右されます:

  • Runnerのexecutorタイプ。
  • ジョブ間でキャッシュを渡すために異なるRunnerが使用されるかどうか。

キャッシュが保存される場所

ジョブに対して定義されたすべてのキャッシュは、単一のcache.zipファイルにアーカイブされます。Runnerの設定では、ファイルの保存場所を定義します。デフォルトでは、キャッシュはGitLab Runnerがインストールされているマシンに保存されます。場所は、executorのタイプによっても異なります。

Runner executorキャッシュのデフォルトパス
Shellローカルでは、gitlab-runnerユーザーのホームディレクトリ(/home/gitlab-runner/cache/<user>/<project>/<cache-key>/cache.zip)にあります。
Dockerローカルでは、Dockerボリューム/var/lib/docker/volumes/<volume-id>/_data/<user>/<project>/<cache-key>/cache.zip)にあります。
Docker Machine(オートスケールRunner)Docker executorと同じです。

ジョブでキャッシュとアーティファクトを使用して同じパスを保存する場合、キャッシュはアーティファクトの前に復元されるため、キャッシュが上書きされる可能性があります。

キャッシュキー名

グローバルフ​​ォールバックキャッシュキーを除き、サフィックスがキャッシュキーに追加されます。

例として、cache.key$CI_COMMIT_REF_SLUGに設定され、2つのブランチであるmainfeatureがあると仮定すると、次の表は結果として得られるキャッシュのキーを表しています:

ブランチ名キャッシュキー
mainmain-protected
featurefeature-non_protected
タグトリガーによるキャッシュサフィックス

パイプラインがタグ($CI_COMMIT_TAGなど)によってトリガーされる場合、キャッシュサフィックス(-protectedまたは-non_protected)は、パイプラインが実行されるブランチではなく、タグの保護ステータスによって決定されます。

この動作により、トリガー参照がキャッシュアクセス許可を決定するため、一貫したセキュリティ境界が確保されます。

たとえば、異なるブランチでパイプラインをトリガーするタグの場合:

トリガーの種類タグ保護ブランチキャッシュサフィックス
タグ0.26.1 (保護されていません)保護されていませんmain (保護)-non_protected
タグ1.0.0 (保護)保護main (保護)-protected
タグdev-123 (保護されていません)保護されていませんfeature (保護されていません)-non_protected
すべてのブランチで同じキャッシュを使用する

キャッシュキー名を使用しない場合は、すべてのブランチ(保護ブランチと保護されていないブランチ)で同じキャッシュを使用できます。

キャッシュキー名を使用したキャッシュの分離はセキュリティ機能であり、この機能を無効にできるのは、デベロッパーロールを付与されているすべてのユーザーの信頼性が極めて高い環境のみです。

すべてのブランチで同じキャッシュを使用するには、次のようにします:

  1. 左側のサイドバーで、検索または移動先を選択して、プロジェクトを見つけます。新しいナビゲーションをオンにしている場合、このフィールドは上部のバーにあります。
  2. 設定 > CI/CDを選択します。
  3. 一般パイプラインを展開します。
  4. 保護ブランチに別のキャッシュを使用するチェックボックスをオフにします。
  5. 変更を保存を選択します。

アーカイブと抽出の仕組み

次の例は、2つの連続するステージでの2つのジョブを示しています:

stages:
  - build
  - test

default:
  cache:
    key: build-cache
    paths:
      - vendor/
  before_script:
    - echo "Hello"

job A:
  stage: build
  script:
    - mkdir vendor/
    - echo "build" > vendor/hello.txt
  after_script:
    - echo "World"

job B:
  stage: test
  script:
    - cat vendor/hello.txt

1台のマシンに1つのRunnerがインストールされている場合、プロジェクトのすべてのジョブが同じホスト上で実行されます:

  1. パイプラインが開始されます。
  2. job Aが実行されます。
  3. キャッシュが抽出されます(見つかった場合)。
  4. before_scriptが実行されます。
  5. scriptが実行されます。
  6. after_scriptが実行されます。
  7. cacheが実行され、vendor/ディレクトリが圧縮されてcache.zipに入れられます。このファイルは、Runnerの設定cache: keyに基づいてディレクトリに保存されます。
  8. job Bが実行されます。
  9. キャッシュが抽出されます(見つかった場合)。
  10. before_scriptが実行されます。
  11. scriptが実行されます。
  12. パイプラインが完了します。

1台のマシンで単一のRunnerを使用すると、job Bjob Aとは異なるRunnerで実行される可能性があるという問題が発生しません。この設定により、複数のステージ間でキャッシュを再利用できることが保証されます。これは、実行が同じRunner/マシン内のbuildステージからtestステージに移行する場合にのみ機能します。それ以外の場合、キャッシュが利用できない可能性があります。

キャッシュプロセス中には、考慮すべき点がいくつかあります:

  • 別のキャッシュ設定がある別のジョブが同じzipファイルにキャッシュを保存した場合、キャッシュが上書きされます。S3ベースの共有キャッシュが使用される場合、ファイルはキャッシュキーに基づいたオブジェクトとしてS3に追加でアップロードされます。したがって、パスが異なる2つのジョブが同じキャッシュキーを持つ場合、キャッシュが上書きされます。
  • cache.zipからキャッシュを抽出する場合、zipファイルのすべての内容がジョブの作業ディレクトリ(通常はプルダウンされるリポジトリ)に抽出され、Runnerは、job Aのアーカイブがjob Bのアーカイブの内容を上書きするかどうかを問題としません。

あるRunnerに対して作成されたキャッシュは、別のRunnerで使用される場合は有効でないことが多いため、このように動作します。異なるRunnerは、異なるアーキテクチャで実行される可能性があります(たとえば、キャッシュにバイナリファイルが含まれている場合)。また、異なるステップは、異なるマシンで実行されているRunnerによって実行される可能性があるため、これは安全なデフォルトです。

キャッシュをクリアする

Runnerはキャッシュを使用して、既存のデータを再利用し、ジョブの実行を高速化します。これにより、一貫性のない動作が発生する場合があります。

キャッシュを新たに始める方法は2つあります。

cache:keyを変更してキャッシュをクリアする

.gitlab-ci.ymlファイルでcache: keyの値を変更します。次回パイプラインが実行されると、キャッシュは別の場所に保存されます。

キャッシュを手動でクリアする

GitLab UIでキャッシュをクリアできます:

  1. 左側のサイドバーで、検索または移動先を選択して、プロジェクトを見つけます。新しいナビゲーションをオンにしている場合、このフィールドは上部のバーにあります。
  2. ビルド > パイプラインを選択します。
  3. 右上隅で、Runnerキャッシュを削除を選択します。

次のコミットで、CI/CDジョブは新しいキャッシュを使用します。

キャッシュを手動でクリアするたびに、内部キャッシュ名が更新されます。名前はcache-<index>の形式を使用し、インデックスは1ずつ増分します。古いキャッシュは削除されません。これらのファイルは、Runnerストレージから手動で削除できます。

トラブルシューティング

キャッシュの不一致

キャッシュの不一致が発生した場合は、次の手順に従って問題を解決してください。

キャッシュの不一致の理由修正方法
共有キャッシュを使用せずに、1つのプロジェクトにアタッチされた複数のスタンドアロンRunner(オートスケールモードではない)を使用している。プロジェクトにRunnerを1つだけ使用するか、分散キャッシュが有効になっている複数のRunnerを使用します。
分散キャッシュを有効にせずに、オートスケールモードでRunnerを使用している。分散キャッシュを使用するようにオートスケールRunnerを設定します。
Runnerがインストールされているマシンでディスク容量が不足してる。分散キャッシュを設定している場合は、キャッシュが保存されているS3バケットに十分な容量がない。新しいキャッシュを保存できるように、必ずスペースを空けておいてください。これを自動実行する方法はありません。
異なるパスをキャッシュするジョブに対して同じkeyを使用している。キャッシュアーカイブが別の場所に保存されるように、かつ間違ったキャッシュを上書きしないように、異なるキャッシュキーを使用します。
Runnerでの分散Runnerキャッシュを有効にしていない。Shared = falseを設定して、Runnerを再プロビジョニングします。

キャッシュの不一致の例1

プロジェクトに割り当てられているRunnerが1つしかない場合、キャッシュはデフォルトでRunnerのマシンに保存されます。

2つのジョブのキャッシュキーが同じでもパスが異なる場合、キャッシュが上書きされる可能性があります。次に例を示します:

stages:
  - build
  - test

job A:
  stage: build
  script: make build
  cache:
    key: same-key
    paths:
      - public/

job B:
  stage: test
  script: make test
  cache:
    key: same-key
    paths:
      - vendor/
  1. job Aが実行されます。
  2. public/cache.zipとしてキャッシュされます。
  3. job Bが実行されます。
  4. 以前のキャッシュ(もしあれば)は、解凍されます。
  5. vendor/cache.zipとしてキャッシュされ、以前のキャッシュを上書きします。
  6. 次回job Aが実行されるとき、異なるjob Bのキャッシュを使用するため、効果がありません。

この問題を修正するには、ジョブごとに異なるkeysを使用します。

キャッシュの不一致の例2

この例では、プロジェクトに複数のRunnerが割り当てられており、分散キャッシュが有効になっていません。

2回目のパイプラインの実行時に、job Ajob Bがそれぞれのキャッシュを再利用するようにしたいとします(この場合は異なります):

stages:
  - build
  - test

job A:
  stage: build
  script: build
  cache:
    key: keyA
    paths:
      - vendor/

job B:
  stage: test
  script: test
  cache:
    key: keyB
    paths:
      - vendor/

keyが異なっていても、後続のパイプラインでジョブが異なるRunnerで実行される場合、キャッシュされたファイルは各ステージの前に「クリーニング」される可能性があります。

同時実行Runnerでローカルキャッシュが見つからない

Docker executorを使用して複数の同時実行Runnerを設定している場合、ローカルにキャッシュされたファイルは、同時実行ジョブに期待どおりに存在しない可能性があります。キャッシュボリュームの名前はRunnerインスタンスごとに一意に構築されるため、あるRunnerインスタンスによってキャッシュされたファイルは、別のRunnerインスタンスのキャッシュでは見つかりません。

同時実行Runner間でキャッシュを共有するには、次のいずれかを行います:

  • Runnerのconfig.toml[runners.docker]セクションを使用して、ホスト上の単一のマウントポイントを構成し、volumes = ["/mnt/gitlab-runner/cache-for-all-concurrent-jobs:/cache"]など、各コンテナの/cacheにマップします。このアプローチにより、Runnerが同時ジョブの一意のボリューム名を作成することを防ぎます。
  • 分散キャッシュを使用します。