前回はあまりキャッシュについて触れることができなかったので、今回はEarthlyが持つキャッシュ機構だけにフォーカスして書く。
Earthlyにおけるキャッシュ
Earthlyは環境に依存しない実行環境を提供するため、キャッシュにおいてもローカルファイルキャッシュのようなホストマシンに依存するタイプのキャッシュ機構*1を提供しない。代わりに、ビルドプロセスの中で SAVE IMAGE
を呼んでいるターゲットの成果物をDockerイメージ化してキャッシュしコンテナレジストリに格納する。ビルドの実行時にはEarthlyが必要なDockerイメージのキャッシュをコンテナレジストリから取得する。
キャッシュイメージをpushするコンテナレジストリとして、使える人はDockerhubを使うのがいいとは思うものの、Dockerhubは無料プランだとレートリミットがかなり厳しくキャッシュとしてreadが頻繁に行われるとすぐ上限に達してしまう。なので、個人利用でEarthlyを使うのならばGithub Container Registryをキャッシュ用のコンテナレジストリとして使うのがおすすめ。
ここからは、Earthlyがキャッシュの機能として2種類提供しているInline cacheとExplicit cacheについて説明する。
Inline cache
ターゲットの成果物であるDockerイメージを個別にキャッシュする。
以下を例としてIzumiSy/go-cleanarchitectureのEarthfile から抜粋。
deps: RUN apk add --no-cache build-base COPY go.mod go.sum . RUN go mod download SAVE IMAGE --cache-hint build: FROM +deps COPY . . RUN go build -o build/go-cleanarchitecture main.go SAVE ARTIFACT build/go-cleanarchitecture AS LOCAL build/go-cleanarchitecture image: COPY +build/go-cleanarchitecture . EXPOSE 8080 ENTRYPOINT ["/go-cleanarchitecture/go-cleanarchitecture"] SAVE IMAGE --push ghcr.io/izumisy/go-cleanarchitecture:cache
上記のEarthfileのうち一番最後の行の SAVE IMAGE --push ghcr.io/izumisy/go-cleanarchitecture:cache
の箇所がInline cacheに該当する。SAVE IMAGE
コマンドは --push
オプションをつけることでリモートのコンテナレジストリにキャッシュとしてのイメージをpushする*2ようになる。なお、キャッシュのソースとなるイメージを別で指定する --cache-from
というオプションもあり、キャッシュのpushとpullでそれぞれ別イメージを指定することもできる。
以上のEarthfileに対して以下のコマンドを実行すると、初回実行時はghcr.io/izumisy/go-cleanarchitecture:cache
にキャッシュイメージが作られ、以降は実行時にキャッシュイメージが使用される。
$ earthly --use-inline-cache --save-inline-cache --push +image
Explicit cache
上のInline cacheの例で抜粋したEarthfileのうち、SAVE IMAGE --cache-hint
の箇所がExplicit cacheに該当するもの。
deps: RUN apk add --no-cache build-base COPY go.mod go.sum . RUN go mod download SAVE IMAGE --cache-hint
Earthlyの実行時には以下のように --remote-cache
オプションでExplicit cacheを格納するDockerイメージの名前を指定する。こちらも --push
オプションがあればキャッシュがコンテナレジストリへpushされる。
$ earthly --push --remote-cache=ghcr.io/izumisy/go-cleanarchitecture-explicit:cache +image
Explicit cacheはEarthfileを通してひとつしか存在しない。Inline cacheのようにEarthfile中に複数異なる名前でキャッシュイメージを指定することはできず、--cache-hint
を指定しているすべてのターゲットのレイヤキャッシュが実行時に --remote-cache
で向けられているキャッシュイメージへすべて格納される。
もしEarthlyの実行時にEarthfile内でExplicit cacheが指定されている場合には、Earthlyは一番最初にこのキャッシュを取得するような動作をする(たぶん)
Inline cacheとExplicit cacheの併用
自分が試した0.6.2時点では、ソースとしての併用はできるが--push
オプションで両方をpushすることはできない。
なので、自分のCircleCIの設定ではコンテナレジストリへのInline cacheイメージのpushはローカルから実行するようにし、CI上ではExplicit cacheのみをpushするようにしている。--use-inline-cache
のオプションはExplicit cacheと併用できる。
jobs: integration-test: machine: true resource_class: large steps: - run: name: Setup docker with ghcr.io command: | docker login ghcr.io --username "izumisy" --password "$DOCKERUSER_TOKEN" - run: name: Setup earthly command: | wget https://github.com/earthly/earthly/releases/download/v0.6.1/earthly-linux-amd64 -O /tmp/earthly chmod +x /tmp/earthly /tmp/earthly bootstrap /tmp/earthly --version - checkout - run: name: Run earthly command: | /tmp/earthly --use-inline-cache --push \ --remote-cache=ghcr.io/izumisy/go-cleanarchitecture-explicit:cache \ +integration-test
ローカルからのInline cacheイメージのpushをするコマンドは次のような雰囲気
$ earthly --push --save-inline-cache +images