ちょっと話題の記事

docker buildを高速化!CodeBuildのローカルキャッシュ機能を試してみる

2019.02.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、かたいなかです。

CodeBuildのローカルキャッシュ機能がリリースされました!

Improve Build Performance and Save Time Using Local Caching in AWS CodeBuild

S3の代わりにビルドを行うホスト上にキャッシュを保存できるようになり、S3への/からのキャッシュの転送時間なしにキャッシュが利用できるようになりました。

また、従来提供されていたbuildspec.yml内で指定したファイルをキャッシュする機能に加え、DockerのイメージのレイヤのキャッシュGitのメタデータのキャッシュも行えるようになりました。

個人的にもDockerのイメージのレイヤのキャッシュによるdocker builddocker pull の高速化がとても良さそうに感じたので早速試してみました。

ローカルキャッシュ機能の概要

従来のCodeBuildのキャッシュ機能ではS3にキャッシュを保存する機能が提供されていましたが、それに加え、S3の代わりにビルドを行うホスト上にキャッシュを保存できるようになりました。ローカルキャッシュを使用することで、今までS3を利用したキャッシュを使用する際にかかっていたS3への/からのキャッシュの転送時間がかからなくなります。

また、ローカルキャッシュではDocker layer cacheSource cacheのモードが提供されています。これにより、DockerのレイヤのキャッシュやGitのメタデータのキャッシュも行えるようになりました。従来のようなbuildspec.ymlで指定したディレクトリをキャッシュすることももちろん可能です。

キャッシュのモード

CodeBuildのローカルキャッシュでは以下の3種類のキャッシュを利用できます。

Docker layer cache

Dockerのイメージのレイヤをキャッシュします。これによりdocker builddocker pull が高速に実行できます。

使用するにはCodeBuildで特権付与フラグを有効にしておく必要があります。

Source cache

Gitのメタデータをキャッシュし、差分のみをpullするようになります。これにより、巨大なモノリシックなリポジトリ等でのソースコードのpullの高速化が望めます。

Custom cache

buildspec.ymlで指定した特定のディレクトリ以下をキャッシュします。従来からのS3にキャッシュを保存する設定と同様の機能です。

例えば以下のようにbuildspec.ymlに記述すると/root/.m2/以下のファイルがキャッシュされます。

cache:
  paths:
    - '/root/.m2/**/*'

ディレクトリ単位でのキャッシュのみで、特定のファイルに対してのキャッシュは行えません。

設定方法

プロジェクトの作成時にローカルキャッシュを設定する

CodeBuildのプロジェクト作成画面から設定するときはArtifactsの設定のところから設定します。Cache typeとしてLocalを選択し、必要なキャッシュのモードを選択します。

既存のプロジェクトにローカルキャッシュを設定する

ローカルキャッシュの設定を行いたいプロジェクトの画面から編集->Artifactsとクリックし、編集画面に移動します。

そして、作成時に設定を行う場合と同様に、Cache typeとしてLocalを選択し、必要なキャッシュのモードを選択します。

DockerのLayer Cachingを試してみる

今回は以下のようなディレクトリ構成のプロジェクトを作成し、試してみます。

.
├── Dockerfile
├── buildspec.yml
├── package-lock.json
├── package.json
└── src
    └── index.js

Dockerfileは以下のようなNode.jsのアプリケーション用のものを使用しています。

Dockerfile

FROM node:10-alpine

ENV APP_ROOT /usr/src/app/

WORKDIR $APP_ROOT

COPY package.json package-lock.json $APP_ROOT
RUN npm install && npm cache clean --force

COPY . $APP_ROOT
EXPOSE 80
CMD ["node", "src/index.js"]

buildspec.ymlは以下のような内容にして、docker buildのみを行うように設定します。

buildspec.yml

version: 0.2

phases:
  build:
    commands:
      ## Dockerイメージのビルド
      - docker build .
#custom cacheを使用する場合
#cache:
#  paths:
#   - directory_path/**/*

Docker layer cacheを有効にしたCodeBuildプロジェクトでキャッシュが効いていない状態で一度ビルドし、その後index.jsを修正した状態で再度ビルドしました。2回目のビルドではDockerfileの8行目のRUN npm install && npm cache clean --forceまでの処理がキャッシュされている想定です。

実際の結果は以下です。上側の2回目のビルドの時間がはっきり短くなっています。

2回目のビルドのログを見てみます。(docker buildの部分だけ抜粋)

Using cacheという文字列からわかるようにレイヤのキャッシュが利用されているのが確認できます。

まとめ

CodeBuildのローカルキャッシュを使用することで、DockerのイメージのLayerをキャッシュしたりGitリポジトリからのpullの高速化が行なえます。また、大量のファイルをキャッシュするときにもキャッシュの転送にかかる時間を気にする必要がなくなります。

個人的にもDockerのイメージのプルやビルドする際の高速化が望めるのはとても嬉しいです。

S3のバケットの用意も不要となり、設定もとても簡単ですのでCodeBuildを使用している際は設定してみてはいかがでしょうか。

参考