私のToDo Appには、Docker Composeを使ってフロントエンドとバックエンドの両方でnpm run testを実行するGitHub Actionsが あります。以前はイメージをビルドしてからテストを実行するのに4分48秒かかっていましたが、buildxキャッシュバックエンドを使うことで、2分18秒にまで短縮されました。レイテンシは2:30短縮され、パフォーマンスは2倍以上向上しました(関連するプルリクエスト)。この記事では、キャッシュの恩恵を受けるために追加できる簡単な手順を紹介します。
TL;DR
以下の2つのステップを追加します:
--- snip ---
jobs:
test_api:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
+ - uses: docker/setup-buildx-action@v2
+
+ - name: Build the backend image with cache
+ uses: docker/build-push-action@v4
+ with:
+ load: true
+ context: backend
+ file: backend/Dockerfile.dev
+ cache-from: type=gha,scope=$GITHUB_REF_NAME-backend-dev
+ cache-to: type=gha,scope=$GITHUB_REF_NAME-backend-dev,mode=max
- name: Start backend
run: docker compose -f docker-compose-dev.yml -f docker-compose-test-single.yml up -d backend
- name: Run test
run: docker compose -f docker-compose-dev.yml exec -T backend npm test -- --watchAll=false
test_frontend:
--- snip ---
解説
docker/setup-buildx-actionはbuildxビルダーのインスタンスをセットアップし、次の
docker`コマンドで使用します。
docker/build-push-action
では3つのオプションが重要です: load
、cache-from
、cache-to
- load
はビルドしたイメージを "buildx の世界" から "docker の世界" にロードし、後続の
dockerコマンドがビルドしたイメージを使用できるようにします。 このオプションがない場合、次の
docker compose up` コマンドはイメージを再度ビルドしてしまいます。なぜなら、ビルド結果は buildx に含まれており、docker には公開されていないからです。 - cache-from
オプションは複数の
typeを受け付けます。その他にも、
registry(コンテナレジストリからキャッシュをロードする) や
local` (ローカルファイルシステムからキャッシュをロードする) などのタイプを指定できます。 - cache-to
オプションは
cache-fromと似ていますが、
modeという重要なオプションも使用できます。mode
をmax
に設定すると、ビルドされたイメージの各レイヤーがキャッシュされ、min
モードでは最終結果のみがキャッシュさ れます。
私の場合、frontend
と backend
の両方を一つの GitHub Actions でビルドしています。そのため、cache-from
と cache-to
に scope
オプションを追加して、これらのキャッシュを区別しています。
YAMLファイル全体
name: Run tests with Docker-Compose and Makefile
on:
workflow_dispatch:
pull_request:
branches:
- main
push:
branches:
- main
jobs:
test_frontend:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: docker/setup-buildx-action@v2
with:
driver: docker-container
- name: Build the [frontend] image with cache
uses: docker/build-push-action@v4
with:
load: true
context: frontend
file: frontend/Dockerfile.dev
tags: |
frontend-test
cache-from: type=gha,scope=$GITHUB_REF_NAME-frontend-dev
cache-to: type=gha,scope=$GITHUB_REF_NAME-frontend-dev,mode=max
- name: Run test
run: docker run --rm frontend-test npm test -- --watchAll=false
test_api:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: docker/setup-buildx-action@v2
with:
driver: docker-container
- name: Build the [api] image with cache
uses: docker/build-push-action@v4
with:
load: true
context: api
file: api/Dockerfile.dev
cache-from: type=gha,scope=$GITHUB_REF_NAME-api-dev
cache-to: type=gha,scope=$GITHUB_REF_NAME-api-dev,mode=max
- name: Start api
run: docker compose -f docker-compose-dev.yml -f docker-compose-test-single.yml up -d --remove-orphans api
- name: Run test
run: docker compose -f docker-compose-dev.yml exec -T api npm test -- --watchAll=false
さいごに
GitHub Actionsに数行追加するだけですが、キャッシュの効果は絶大でした。 本記事が日頃の開発に役立てば幸いです。