銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

.NET 7で導入されたビルトインコンテナサポートを試してみた

.NET 7になって .NET SDKだけでコンテナのビルドができるようになりました。

devblogs.microsoft.com

このブログの最初にある通り、Microsoft.NET.Build.Containers というライブラリを追加すると利用できる機能ですが、(temporary)とあるのでそのうち不要になる(SDKなどに組み込まれる)かもしれません。dotnet publish --os linux --arch x64 -c Release -p:PublishProfile=DefaultContainerというようにdotnet publishコマンドだけでコンテナイメージのビルドが実行されます。

% dotnet publish --os linux --arch x64 -c Release -p:PublishProfile=DefaultContainer

MSBuild version 17.4.0+18d5aef85 for .NET
  復元対象のプロジェクトを決定しています...
  復元対象のすべてのプロジェクトは最新です。
  my-awesome-container-app -> /Users/ttanaka/Repos/my-awesome-container-app/bin/Release/net7.0/linux-x64/my-awesome-container-app.dll
  my-awesome-container-app -> /Users/ttanaka/Repos/my-awesome-container-app/bin/Release/net7.0/linux-x64/publish/
  Building image 'my-super-awesome-app' with tags 1.2.3-alpha2,latest on top of base image mcr.microsoft.com/dotnet/aspnet:7.0-alpine
  Pushed container 'my-super-awesome-app:1.2.3-alpha2' to Docker daemon
  Pushed container 'my-super-awesome-app:latest' to Docker daemon

プロジェクトのどこかにDockerfileが作成されるわけでもなく、内部でビルドが行われます。

また、ビルドしたイメージはデフォルトでdocker://のdocker daemonへとpushされます。

ビルドされるイメージをカスタマイズしたい場合、現時点で利用可能な設定がこちらにあります。PropertyGroupに指定するものと、ItemGroupに指定するものがあります。

github.com

例えばこのように指定します。

  <PropertyGroup>
    <ContainerBaseImage>mcr.microsoft.com/dotnet/aspnet:7.0-alpine</ContainerBaseImage>
    <ContainerImageName>my-super-awesome-app</ContainerImageName>
    <ContainerImageTags>1.2.3-alpha2;latest</ContainerImageTags>
    <ContainerRegistry>registry.mycorp.com:1234</ContainerRegistry>
  </PropertyGroup>
  • ContainerBaseImage:ビルドするイメージのベースイメージ。デフォルトではプロジェクトの種類に応じて決められる。
  • ContainerImageName:ビルドしたイメージの名前
  • ContainerImageTagあるいはContainerImageTags:ビルドしたイメージに付与するタグ。1つの場合はContainerImageTagで、複数の場合はContainerImageTags。ただし、ContainerImageTagsは後述のバグがあり回避策が必要。
  • ContainerRegistry:pushするレジストリ。今の所認証不要なレジストリのみサポート。

デフォルトでベースとなるイメージはプロジェクトの種類に応じて以下のようになります。

  • ASP.NET Core アプリの場合、mcr.microsoft.com/dotnet/aspnet
  • 自己完結型アプリの場合、mcr.microsoft.com/dotnet/runtime-deps
  • 他のすべてのアプリでは、mcr.microsoft.com/dotnet/runtime

ContainerImageTagsでタグを複数指定したい場合、既知の不具合があるため以下の設定をcsprojに追加して回避します。

  <ItemGroup>
    <!-- Work around https://github.com/dotnet/sdk-container-builds/issues/236 -->
    <ContainerImageTags Include="$(ContainerImageTags)" />
  </ItemGroup>

便利なようですが、いくつか現時点での制約があります。

  • Linux x64アーキテクチャのイメージのみサポート
  • 認証なしのリポジトリへのpushのみサポート

また、run commandの変更はサポートしない方針と記載されています。

以上をふまえると現状ではブログにある通り、ローカル開発環境や認証なしのリポジトリにプッシュするようなCI/CDでの利用がメインとなりそうです。