CircleCIのリモートDocker環境でBuildKitとレイヤーキャッシュを使えるようにする


CircleCIでDockerイメージをビルドするときに、何も設定していないとキャッシュが効かなかったり、マルチステージビルドを使ってると並列ビルドが効かなかったりして時間が無限に溶けていってしまっていました。

ここで、ちゃんと設定して使えるようにする方法を記したいと思います。

レイヤーキャッシュを使えるようにする

とても簡単です。リモートDocker環境をセットアップするときに有効にしましょう。

jobs:
  docker-image-build-job:
    steps:
      - setup_remote_docker:
          version: 20.10.11
          # ここでセットアップ時に有効にする
          docker_layer_caching: true

docker_layer_caching: true を指定してあげることで有効にできます。

参考: https://circleci.com/docs/ja/2.0/docker-layer-caching/#remote-docker-environment

以前はレイヤーキャッシュは有償プランでしか使用できませんでしたが、プランのページを見ると現在はFreeプランでも使用可能になっています。

参考: https://circleci.com/ja/pricing/

BuildKitを使えるようにする

前提条件

大前提として、BuildKitが使えるバージョンのDockerがリモートDocker環境とexecutorの双方に入っていることが条件になります。

どちらかが欠けているとBuildKitは使えないので注意してください。

どのイメージにどのバージョンのDockerが含まれているかはCircleCIのイメージのページに記載されているので確認しましょう。

例として、cimg/php:8.0.17が内包しているパッケージを確認したところ以下のようになっていました。

build-essential 12.8ubuntu1.1, composer 2.1.12, curl 7.68.0, docker 20.10.12, docker-compose-v1 version, docker-compose-v2 /usr/local/bin/docker-compose version, dockerize v0.6.1, git 2.34.1, jq 1.6, php 8.0.17, ubuntu 20.04.3 LTS, wget 1.20.3

この場合は docker 20.10.12 となっていましたので使えますね。
(使えないバージョンを指定していてめっちゃハマったので要注意です)

設定する

設定自体はものすごく簡単です。

jobs:
  docker-image-build-job:
    # 環境変数で有効化の指定をする
    environment:
      DOCKER_BUILDKIT: 1
    steps:
      - setup_remote_docker:
          version: 20.10.11
          docker_layer_caching: true

DOCKER_BUILDKIT=1 という環境変数があるとBuildKitが有効になるので、environmentで設定してしまいましょう。

外部のCircleCI Orbを使う場合にコマンドを書き換えられないときにも有効化できるので個人的にはenvironmentで有効にするのがおすすめです。