前提
開発環境をdocker compose up
一発で立ち上がるようにすると大変便利です。
当然GithubActions環境下でも同じようにコンテナを起動し、testやlintを実行したいところです。
しかし2021年12月31日現在、GithubActionsではdocker composeは何もしなくても使えるものの、BuildKitはデフォでは入っておらず、dockerのlayer cacheも勝手にはやってくれません。
ということで、毎回docker compose up -d
でコンテナビルドをやり直さなくて済むようにBuildKitのcacheをgithub actionsに残していきたいと思います。
とりあえず成果物
この辺がキャッシュしてる部分になります
1つずつ何をしてるか確認していきます。
まずはcache
actions/cache
を使ってBuildKitのcacheを保持します。
ここではpoetry.lock
のhashをkeyにしていますが、適宜パッケージマネージャのlockファイルなどに読み替えてください。
キャッシュするpathはどこでも構いません。
次にBuildKitのcache更新
ここが1つ目のミソです。
actions/cache
によってrestoreされたBuildKitのキャッシュを使ってコンテナイメージを作成したいところですが、このままコンテナイメージ作成を行うとキャッシュに変更があった場合に追加されます。
このまま開発していくとキャッシュがどんどん増え、GithubActionsのキャッシュ上限に引っかかるところまで行ってしまいます。
そこで一手間挟み、現在のキャッシュを使ってbuildを行いそこで発生したキャッシュのみを保存することにします。
まず,docker builder build
コマンドの--cache-from
で先程restoreしたディレクトリを指定し、--cache-to
で新しいBuildKitのキャッシュを作ります。
そして、新しく作ったBuildKitキャッシュディレクトリをactions/cache
が保存してくれるディレクトリに上書きしてしまいます。
こうすることで古いキャッシュを消し新しいキャッシュのみを保存します。
そしてdocker compose up
なのですが、何故かGithubActions上のdocker composeはBuildKitを使ってくれませんでした。(原因掘ってないのでご存知の方はご一報を)
ということで、2つ目のミソです。
BuildKitを使うdocker builder
以下にはbakeコマンドがあり、これはHCLやjson, ymlなどからbuildを行うことができます。
この機能を使ってdocker compose up
前にコンテナイメージを作成してしまいます。
オプションが良くわからない感じですが、--load
はドキュメントにあるようにローカルのdocker daemonにイメージを保存するということで、-set *.cache-from=type=local,src=/tmp/.buildx-cache
はビルド時のcacheを先程上書きしたactions/cache
から読み込むという指定です。
これにより、BuildKitのキャッシュを使ってdocker daemonにイメージを作ることができ、ようやくdocker compose up
する準備が整いました。
追記
docker builder build
で古いキャッシュから新しいキャッシュを作っていましたが、これだとdocker-compose.ymlに書いたことが使えないのでここでもbakeコマンドを使った方が楽でした。