Integration Tests: Build Images Once and Switch to fuse‑overlayfs
Integration tests for Kamal were taking longer because Docker images were rebuilt on every test run and the default VFS storage driver conflicted with nested overlay mounts. The PR replaces the per‑run rebuild with a single build and adopts fuse‑overlayfs to avoid overlay‑on‑overlay failures. These changes keep the test behaviour identical while reducing overall execution time.
背景
Integration test suites that spin up Docker‑in‑Docker environments must construct images before each run, which adds several minutes to the total runtime. Additionally, the previous configuration used the VFS storage driver, which cannot nest overlay filesystems and therefore required the container to fall back to a slower copy‑on‑write mode. Both factors caused unnecessary latency without providing functional benefits, motivating a redesign of the test harness.
技術的な変更
イメージのビルドを一度だけ実行するロジックが追加されました。テスト実行中に $IMAGES_BUILT フラグを確認し、未ビルドの場合にのみ docker_compose "build" を走らせます。新たに導入された build_images_once メソッドは compose_up_with_retry の先頭で呼び出され、以降の up は --no-build オプションでビルドをスキップします。
@@
def compose_up_with_retry
- docker_compose "up --build -d"
+ build_images_once
+ docker_compose "up -d --no-build"
@@
def build_images_once
- # existing logic removed
+ return if $IMAGES_BUILT
+ docker_compose "build"
+ $IMAGES_BUILT = true
end
Dockerfile では fuse‑overlayfs パッケージをインストールする行が追加され、VFS に依存しないストレージドライバが利用可能になりました。これにより、Docker デーモンが内部で overlay2 を使用でき、ネストされたオーバーレイでも高速に動作します。
@@
-RUN apt-get update --fix-missing && apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
+RUN apt-get update --fix-missing && apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin fuse-overlayfs
同様の変更が test/integration/docker/vm/Dockerfile にも適用され、VM コンテナでも同一パッケージが利用可能です。
@@
-RUN apt-get update --fix-missing && apt-get -y install openssh-client openssh-server docker.io
+RUN apt-get update --fix-missing && apt-get -y install openssh-client openssh-server docker.io fuse-overlayfs
boot.sh スクリプトは storage-driver を fuse‑overlayfs へ変更し、デーモン設定を更新しています。コメントも更新され、overlay2 がネストできない状況で fuse‑overlayfs がコピーオンライトを提供する旨が明記されています。
@@
- "storage-driver": "vfs",
+ "storage-driver": "fuse-overlayfs",
@@
- "storage-driver": "vfs",
+ "storage-driver": "fuse-overlayfs",
docker_compose "down" のタイムアウトが -t 1 から即時停止を意味する -t 0 へ変更され、テスト終了時のクリーンアップが迅速化されました。また、compose_up_with_retry の失敗時リトライロジックでも同様に即時停止が適用されています。
@@
- docker_compose "down -t 1"
+ docker_compose "down -t 0"
@@
- docker_compose "down -t 1", raise_on_error: false
+ docker_compose "down -t 0", raise_on_error: false
設計判断
fuse‑overlayfs を選択した理由は、Docker の overlay2 がネストされたオーバーレイをサポートせず、VFS では毎回全レイヤをコピーするためパフォーマンスが低下する点にあります。fuse‑overlayfs はカーネル空間の overlay2 と同様のコピーオンライト機構をユーザースペースで提供し、特権コンテナ内でも安全に使用できます。この選択は既存テストの挙動を変えずに、内部ストレージの効率化を実現します。
ビルドの重複を防ぐために グローバル変数 $IMAGES_BUILT と build_images_once を導入した設計は、テストコードのシンプルさを保ちつつビルドコストを一次化します。フラグチェックは軽量であり、テスト全体のフローにほとんど影響を与えません。これにより、テスト実行時間の削減が保証されます。
まとめ
本 PR は、画像ビルドの一回化と fuse‑overlayfs へのストレージドライバ切替という二つの改良で、Kamal の統合テスト速度を大幅に向上させました。機能的な振る舞いは変わらず、テスト環境の構成がシンプルかつ高速になった点が主な成果です。