2019/3/4追記
CodeBuildが公式でDockerのレイヤーキャッシュに対応しました
docker buildを高速化!CodeBuildのローカルキャッシュ機能を試してみる
以降はこちらの方法でキャッシュ有効にするのが良いと思います。
※上記方法は --cache-from
を指定しているとキャッシュ効かないみたいなので、気をつけて下さい。
はじめに
CodeBuildはコンテナレイヤーのキャッシュには対応していないため、
コンテナベースのCI/CDをCodeBuild上で構築している場合は
毎回フルスクラッチでビルドし直す必要があり、とても時間がかかってしまいます。
このビルド時間を少しでも軽減するテクニックとして、ビルド済みのECRのコンテナイメージを
pullして--cache-from
で使用するというものがあるので紹介します。
前提
ビルド環境に入っているdockerが--cache-from
をサポートしている必要があります。
公式イメージを使用してビルドするなら Docker 17.09
以上を選択すればOKです。
また、オリジナルイメージを使用してビルドするならこちらの記事が参考になります。
AWS CodeBuild カスタムDockerイメージを使ってビルドする
docker buildでキャッシュを使う
buildspecを以下のように書きます。ポイントは2つ、
- buildする前にECRにログインしてコンテナイメージを引っ張ってくる
- buildの引数に--cache-fromを付けて、引っ張ってきたイメージを使用する
だけです。
version: 0.2
phases:
pre_build:
commands:
- $(aws ecr get-login --no-include-email)
- docker pull $REPOSITORY_URL:$TAG_NAME || true
build:
commands:
# --cache-fromをつけることで、爆速になる
- docker build --cache-from $REPOSITORY_URL:$TAG_NAME -t $REPOSITORY_URL:$TAG_NAME .
# 作ったあとはこのように呼び出してよしなにいろいろやる
- docker run --rm $REPOSITORY_URL:$TAG_NAME npm run test
- docker run --rm $REPOSITORY_URL:$TAG_NAME npm run lint
post_build:
commands:
# deployならpushもいつもどおりやる
- docker push $REPOSITORY_URL:$TAG_NAME
念のためですが…
-
$REPOSITORY_URL
や$TAG_NAME
は環境変数です。実際のURLは
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/hoge/fuga:develop
みたいな感じになりますかね。 - タグは適宜付けて下さい
また、公式イメージ以外を使ってビルドする場合はinstallフェーズにDockerデーモンを立ち上げて
利用可能になるまで待機するコマンドを足す必要があります。
公式イメージをベースに自分で作ったコンテナを使用する場合もこれが必要なので注意
version: 0.2
phases:
install:
commands:
- nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 --storage-driver=overlay&
- timeout -t 15 sh -c "until docker info; do echo .; sleep 1; done"
pre_build:
.
.
.
docker-compose buildでキャッシュを使う
基本的にdocker buildと変わりませんが、コマンドラインの引数として--cache-from
を渡すのではなく、
docker-compose.ymlファイルにcache_from
項目を足して指定します。
docker-composeのversionは 3.2
以上を指定しないと対応していないので注意して下さい。
ちなみに、cache_from
は複数指定できるみたいです。その場合は最初にHITした
イメージがキャッシュとして使われ、HITしなかった場合は自前でビルドされます。
version: 0.2
phases:
pre_build:
commands:
- $(aws ecr get-login --no-include-email)
- docker pull $REPOSITORY_URL:$TAG_NAME || true
build:
commands:
docker-compose build test
docker-compose run test
version: '3.2' # 3.2以上じゃないと対応していないので注意!!!
services:
.
.
.
test:
build:
context: .
# これ!!
cache_from:
- $REPOSITORY_URL:$TAG_NAME
command: npm run test
終わりに
キャッシュと言いつつ、厳密にCodeBuildを走らせる環境にローカルキャッシュされたものを
使っているのではなく、結局ECRからpullしてるので、pullして取ってくる部分のオーバーヘッドが
あるということは意識しないといけません。
適切に設計されたdockerコンテナイメージであれば大抵速くなると思いますが、
レイヤー構成的に半分くらいしかキャッシュが効かなくて結局半分くらい自前で
ビルドする必要があるようなイメージや、データ量だけ多くて馬鹿みたいにデカい
コンテナイメージ等はむしろpullする部分のオーバーヘッド分で逆に遅くなることもあります。
逆に、データ量は少ないけどCPUをぶん回す必要があるようなコンテナは
劇的なスピードアップを見込めると思います。
なので、キャッシュを使用する価値があるかどうかは実際に試してみて判断して下さい。