🐳

Github Actionsでdocker composeのlayer cacheを使って実行時間を約3分短縮

に公開

背景

  • GitHub Actions で CI を回しています。
  • 昔にセットアップしたプロジェクトで GitHub Actions の cache 機能が使われていませんでした。

アプローチ

  • いろいろな設定方法がありますがコード量が多くてきれいじゃないです。
  • docker compose を利用しているので Docker の build cache を流用できたら楽だなぁと思ってました。
  • CircleCI では Docker レイヤーキャッシュ (DLC)によってbuild cache が保管されるのですが GitHub Actions ではこれに対応する機能がありません。
  • 今回見つけた actions では、GitHub Actions の Cache 機能を使って DLC をエミュレートしてくれるような動きをしてくれます。

設定

差分はこれだけです。
この追加した action の中でキャッシュストレージへの保存と読み込みをやってくれます。


jobs:
  rspec:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    env:
      TZ: Asia/Tokyo
      RAILS_ENV: test
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive
+      - uses: docker/setup-buildx-action@v2
+      - uses: docker/build-push-action@v4
+        with:
+          context: .
+          cache-from: type=gha
+          cache-to: type=gha,mode=max
      - name: Setup docker
        shell: bash
        run: |
          docker compose -f docker-compose.ci.yml build --progress=plain
          docker compose -f docker-compose.ci.yml pull -q

上記の設定を入れた上で、GitHub Actions で CI を回してみた結果です。

実行

Actions の Caches には以下のように保存されています。

ベンチマーク

CI 全体で 2 分 47 秒が短縮されました。
実行時間比率で言えば、19.8%短縮しました。

実行時間の内訳

3 分 29 秒かかっていた build が 42 秒で終わるようになっています。

初回実行

cacheからロードして実行

考察

  • Docker build にタグ付けしてロードしたりキャッシュしたりするようなロジックを書いているケースに対しても、今回紹介した設定に置き換えるだけで同等の効果があると思います。
  • 今までは、キャッシュの操作を手動で書いていたのが、Docker の中間キャッシュに完全に任せられるので楽になると思います。
  • Dockerの中間キャッシュを使うロジックを理解した上で使う必要があります。
  • 今回は rspec 用のテストの紹介ですが、ECS に deploy するときの image を作る際にも使えると思います。

まとめ

  • GitHub Actions の Cache を使って、Docker compose の build 時に使用する layer cache を有効利用するようにしました。
  • 実行時間が 3 分近く短縮しました。
株式会社マインディア テックブログ

Discussion