はじめに
GitHub ActionsでDockerのコンテナをBuildするとデフォルトだとLayerのCache?がされないため、毎回Dockerfileの先頭から実行することになります(何も工夫をしないと)。
「LocalでBuildするときは(Cacheが効いて)速いんだけど、GitHub Actionsだと遅い」というのは、Buildに時間がかかる場合結構しんどいです(Twitterなどが捗ってしまう)。
色々方法があるようですが、Dockerのマルチステージビルドを使っていないなら、割と簡単にCacheを効かせられるようなので、そのメモです(主に自分用)。
Docker BuildでCacheを効かせる方法
ポイントは docker buildコマンドの --cache-from
と --build-arg BUILDKIT_INLINE_CACHE=1
になります。また、このOptionを指定するには、BuildKitを有効にしないといけないので、環境変数 DOCKER_BUILDKIT=1
を指定しておくことが必要になります(buildx でも良いようですが)。
上記リンクのドキュメントにも書いてありますが、それぞれ次のような意味になります。
-
--cache-from
: CacheSourceを指定するコマンドで、外部リポジトリを指定すると適宜アクセスしてくれるようです。 -
--build-arg BUILDKIT_INLINE_CACHE=1
: Build時にMeta情報を埋め込み、--cache-from
で使えるようにします。これをリポジトリにPushしておけば、前回Build時のLayerを再利用できるようになります。 - 環境変数
DOCKER_BUILDKIT=1
: こう設定しておくとBuildKitが有効になるようです。GitHub Actionsでも使えるようです。
サンプル
例えば、AWSのECRにPushする場合は、以下のように書くことができます。
on:
push:
tags: release-* # トリガーは `release-****` というTagがPushされたとき
name: Push to Amazon ECR
jobs:
push:
name: BuildAndPush
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
DOCKER_BUILDKIT: 1 # これ大事
ECR_REGISTRY: 999999999999.dkr.ecr.ap-northeast-1.amazonaws.com # TODO: 要変更
ECR_REPOSITORY: my-awesome-container # TODO: 要変更
IMAGE_TAG: ${{ github.sha }}
run: |
# latest と github.sha でタグをふる場合
docker build \
--cache-from=$ECR_REGISTRY/$ECR_REPOSITORY:latest --build-arg BUILDKIT_INLINE_CACHE=1 \
-t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -t $ECR_REGISTRY/$ECR_REPOSITORY:latest .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
さいごに
actions/cache@v2
とか使うともっと良い(速い)のかもしれないですが、使わなくてもできるんだな、と思ったのでメモしておきます。