サーバレスアーキテクチャ

Gitlab CI/CD Pipelineでキャッシュを使う方法

Gitlab CI/CD Pipelineでビルド時間を大幅に短縮できる「キャッシュ」の設定方法や仕組み、キャッシュ有無でのビルド時間の短縮効果をまとめました。

Gitlab CI/CD Pipelineでのキャッシュとは

Gitlab CI/CD Pipelineでは、幅広い範囲でキャッシュを利用できます。キャッシュの設定は、Gitlab CI/CDのビルド設定を記述する「.gitlab-ci.yml」で設定します。

Cache dependencies in GitLab CI/CD| Gitlab Docs

Gitlab CI/CD Pipelineでのキャッシュは大きく分けて二つあって、

  • cache
  • artifacts

それぞれ用途が違うため、使い方が変わってきます。

cache設定

cache設定は、アプリのビルドに使うプラグインなどの依存ファイルをキャッシュする設定です。

cacheの特徴は、

  • 後に実行されるpipelineでもcacheで設定したファイルは使い回しされる
  • 使い回しがされるので、ダウンロードや依存プログラムのビルド時間が短縮される
  • キャッシュファイルはダウンロードできない

という点です。

Node.jsで言えば「npm build (yarn install)」、Rubyで言ったら「bundle install」の時間短縮に使うものと考えれば良いでしょう。

artifacts設定

artifacts設定は、Gitlab Pagesで使われる設定ですが、Gitlab Pages専用の設定というわけではなく、「ビルド済みのファイルを、同一pipelineで使い回す」設定と考えればわかりやすいでしょう。

  • 同一pipelne内でファイルを共有する
  • 別のpipelineではキャッシュが利用されない
  • キャッシュファイルは、Gitlab管理画面からダウンロードできる

という特徴があります。

キャッシュという視点で見ると、先ほどの「cache設定」と違って、後に実行されるpipelineではキャッシュが再利用されないため、

  • 毎回、ビルド・生成する必要があるファイル
  • 複数のjobをまたいで使うファイル

を「当該Pipelineの間だけキャッシュ」すると覚えると良いでしょう。

cacheとartifactsの比較

cacheとartifactsの比較をまとめてみました。

項目 cache artifacts
pipeline間のキャッシュ共有 ×
job、script間のキャッシュ共有
キャッシュファイルのダウンロード ×
使い方例 パッケージのキャッシュ ビルド済みファイルの共有

Gitlabのキャッシュの設定方法

実際に、キャッシュを使う設定をしてみましょう。Node.jsアプリのビルドをサンプルに、cacheを使ってPipeline時間の短縮させてみます。

.gitlab-ci.ymlの例

Node.jsアプリの設定例です。

image: node:latest

variables:
  GIT_SUBMODULE_STRATEGY: recursive

pages:
  stage: deploy
  only:
    - master
  cache:
    paths:
      - .cache/    
  before_script:
    - mkdir -p .cache
    - npm config set cache $CI_PROJECT_DIR/.cache/npm --global
    - yarn config set cache-folder $CI_PROJECT_DIR/.cache/yarn
    - yarn install
  script:
    - yarn build
    - mv public public_org && mv dist public
  artifacts:
    paths:
      - public

設定をみていくと、まず、

cache:
  paths:
    - .cache/    

でcacheするディレクトリを指定します。この場合、Gitlab CI/CDが利用するnode.js・dockerコンテナ内のworkディレクトリに作成する「.cache」ディレクトリをキャッシュとして指定します。

続いて、ビルドを行う前の「before_script」部分(依存ファイルの生成を実行している)で、

before_script:
  - mkdir -p .cache
  - npm config set cache $CI_PROJECT_DIR/.cache/npm --global
  - yarn config set cache-folder $CI_PROJECT_DIR/.cache/yarn
  - yarn install
  • .cacheディレクトリを作成
  • npmとyarnでcacheディレクトリを設定
  • 依存ファイルをインストール

ということをやっています。

実際にキャッシュを使ってビルド&効果測定

ビルド実行&ログ

先ほどの.gitlab-ci.ymlを使って、実際にビルドをしてみます。

ビルドログをみてみると、

.
.
.
Checking cache for default...
Downloading cache.zip from https://storage.googleapis.com/gitlab-com-runners-cache/project/xxxxxxxx/default
Successfully extracted cache
.
.
.

というログが増えています。

これは、キャッシュファイルをGitlabが管理するGoogle Cloud Storage上に保存したものと同期しているようです。

.
.
.

Creating cache default...
.cache/: found 32910 matching files                
Uploading cache.zip to https://storage.googleapis.com/gitlab-com-runners-cache/project/xxxxxxxx/default
Created cache
.
.
.

続いて、ビルドが終わった後に、キャッシュ対象ディレクトリをzipで固めて、再度Google Cloud Storage上にアップロードしています。

つまり、cacheで設定したディレクトリは、

  • Jobが終わった後にGitlabが管理するGCSにアップロードされる
  • 次のJobのscript実行前に、GCSから同期される

ということのようです。

キャッシュの効果測定:どれくらいPipeline時間を短縮できるか

Node.jsアプリで、パッケージをキャッシュを使った場合とキャッシュした場合でPipeline時間を比較してみました。

cacheあり cacheなし
パッケージビルド 13.10s 114.04s
全体 00:01:41 00:03:13

パッケージビルドについては、1/10に、全体のビルド時間はおおよそ、半分くらいになりました。

ここは、パッケージビルド時間が長ければ長いほど、短縮時間に効果的になります。


Gitlab CI/CD Pipelineでキャッシュを使う設定をみてきました。

重要なポイントは、

  • .gitlab-ci.ymlで「cacheのディレクトリ」を指定する
  • パッケージマネージャーで、指定したcacheディレクトリを利用させる

という2つのポイントだけなので、ここさえ出来ればどんな言語でも利用できます。

キャッシュを使うことで「ビルド時間の短縮」「Pipelineの割り当て時間を節約」という大きなメリットがあるので、ぜひ使ってみてください。


価格は記載がある場合を除き、すべて税込みです。

この記事の関連キーワード

サーバレスアーキテクチャの記事