14
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

弥生Advent Calendar 2024

Day 4

.NET8で開発しているマイクロサービスのバックエンドのdocker composeが遅すぎるので頑張って高速化してみた

Posted at

概要

マイクロサービスアーキテクチャで開発をしており、各サービスをDockerでコンテナにしています。ローカル環境の各コンテナを最新化する際に、docker-compose up --build -dがすべて終わるまでに20~30分毎回かかってしまっていたので、頑張って高速化してみました。体感、3~4分ぐらいまで高速化できたと思います。Windows環境での開発を前提としています。また、1つ1つの効果を細かく測定はしていないので、それぞれの対応がどれだけ効果があったかは体感になります。(測定したら記事を更新したいと思います。)

やってみた事

  1. BuildKitのインラインキャッシュの利用
  2. BuildKitのマウントキャッシュの利用
  3. 並列ビルドの利用
  4. Buildステージに軽量なイメージを利用する
  5. DBのMigration時にビルド済みのリソースをちゃんと使う

BuildKitのインラインキャッシュの利用

BuildKitのインラインキャッシュは、Dockerイメージのレイヤーにビルドキャッシュを埋め込む機能です。通常のDockerビルドキャッシュと異なり、イメージ自体にキャッシュ情報が含まれるため、異なるマシンやCI環境でもキャッシュを再利用できます。ローカル環境でも、同じDockerfileから何度もビルドを行う場合に効果がありそうなので、試してみました。

以下のようにBUILDKIT_INLINE_CACHE: 1を記述しておきます。

# docker-compose.yml
services:
  backend-service:
    build:
      context: ./backend
      dockerfile: Dockerfile
      args:
        BUILDKIT_INLINE_CACHE: 1

BuildKitのマウントキャッシュの利用

BuildKitのマウントキャッシュを使用することで、NuGetパッケージのリストア処理を効率化しました。このキャッシュはホストマシン上に保持され、ビルド時のみ一時的にマウントされます。Dockerfileでは以下のように設定します。

RUN --mount=type=cache,target=/root/.nuget/packages dotnet restore "Hoge.csproj"
RUN --mount=type=cache,target=/root/.nuget/packages dotnet build "Hoge.csproj" -c Release

ローカルのNuGetパッケージのキャッシュをコピーする事も考えましたが、各端末の開発環境の影響が大きかったため、中止しました。環境がかなり統一されている状況なら使えるかもしれません。

並列ビルドの利用

PCのスペックが高くない場合は効果が薄かったり、負荷がかかりすぎるかもしれませんが、幸いな事にそれなりのスペックだったこともあり、かなり効果があったと思います。

docker compose build --parallel

Buildステージに軽量なイメージを利用する

Buildステージのみ、alpine版にして少しでも処理が軽くならないか期待してみました。高速化の観点ではそこまで効果は無かった印象です。

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS buildFROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build

DBのMigration時にビルド済みのリソースをちゃんと使う

docker compose build --parallelの後にdocker compose up -dでコンテナを起動し、DBのMigrationを実行してローカルのDB環境を構築していました。Entity Framework Core CLIを利用して、Migrationを実行していましたが、実行時にBuildから実行されており、なぜかBuildに5分以上の時間がかかっていました。イメージを作成する際にビルド済みなので、それを使う事によりこの5分以上の時間を短縮する事ができました。

ENTRYPOINT [ "dotnet", "ef", "database", "update", "--no-build", "--configuration", "Release" ]

まとめ

いろいろな最適化手法があり、組み合わせる事でメリットが得られます。
今回は、特にBuildKitのマウントキャッシュと並列ビルドの組み合わせが効果的でした
実際の環境に合わせて各設定を調整し、最適なパフォーマンスを探してみてください。

14
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?