dotnet publish を使用して .NET アプリをコンテナー化する
コンテナーには、変更できないインフラストラクチャになったり、移植可能なアーキテクチャを提供したり、スケーラビリティを可能にしたりといった、さまざまな特徴とベネフィットがあります。 そのイメージを使って、ローカル開発環境、プライベート クラウド、またはパブリック クラウド用にコンテナーを作成することができます。 このチュートリアルでは、dotnet publish コマンドを使用して .NET アプリケーションをコンテナー化する方法について説明します。
必須コンポーネント
次の前提条件をインストールします。
- .NET 8+ SDK
.NET がインストールされている場合は、dotnet --info
コマンドを使用して、使用している SDK を特定します。 - Docker Community Edition
- .NET 7+ SDK
.NET がインストールされている場合は、dotnet --info
コマンドを使用して、使用している SDK を特定します。 - Docker Community Edition
これらの前提条件に加えて、.NET の Worker サービスについて理解しておくことが推奨されています。
.NET アプリの作成
コンテナー化する .NET アプリが必要であるため、まずテンプレートから新しいアプリを作成します。 ターミナルを開き、作業フォルダー (sample-directory) がまだない場合は作成し、そこに移動するようにディレクトリを変更します。 作業フォルダーで次のコマンドを実行し、Worker という名前のサブディレクトリに新しいプロジェクトを作成します。
dotnet new worker -o Worker -n DotNet.ContainerImage
フォルダー ツリーは次のようになります:
📁 sample-directory
└──📂 Worker
├──appsettings.Development.json
├──appsettings.json
├──DotNet.ContainerImage.csproj
├──Program.cs
├──Worker.cs
└──📂 obj
├── DotNet.ContainerImage.csproj.nuget.dgspec.json
├── DotNet.ContainerImage.csproj.nuget.g.props
├── DotNet.ContainerImage.csproj.nuget.g.targets
├── project.assets.json
└── project.nuget.cache
dotnet new
コマンドは、Worker という名前の新しいフォルダーを作成し、実行されると 1 秒ごとにメッセージをログに記録するワーカー サービスを生成します。 ターミナル セッションから、ディレクトリを変更して Worker フォルダーに移動します。 dotnet run
コマンドを使用してアプリを起動します。
dotnet run
Building...
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:00 -05:00
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: .\Worker
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:01 -05:00
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:02 -05:00
info: DotNet.ContainerImage.Worker[0]
Worker running at: 10/18/2022 08:56:03 -05:00
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
Attempting to cancel the build...
ワーカー テンプレートは無期限にループします。 停止するにはキャンセル コマンド Ctrl + C を使用します。
NuGet パッケージを追加する
現在、Web 以外のプロジェクトをコンテナーとして発行するには Microsoft.NET.Build.Containers NuGet パッケージが必要です。 Microsoft.NET.Build.Containers
NuGet パッケージをワーカー テンプレートに追加するには、次の dotnet add package コマンドを実行します。
dotnet add package Microsoft.NET.Build.Containers
ヒント
Web アプリを構築していて、.NET SDK 7.0.300 以降を使用している場合、このパッケージは不要です。その SDK には、すぐに使用できる同じ機能が含まれています。
コンテナー イメージ名を設定する
アプリをコンテナーとして公開するときに使用できるさまざまな構成オプションがあります。
既定で、コンテナー イメージ名はプロジェクトの AssemblyName
になります。 その名前がコンテナー イメージ名として無効な場合は、次のプロジェクト ファイルに示すように ContainerRepository
を指定してオーバーライドできます。
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-DotNet.ContainerImage-2e40c179-a00b-4cc9-9785-54266210b7eb</UserSecretsId>
<ContainerRepository>dotnet-worker-image</ContainerRepository>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>
</Project>
詳細については、「ContainerRepository」を参照してください。
既定で、コンテナー イメージ名はプロジェクトの AssemblyName
になります。 その名前がコンテナー イメージ名として無効な場合は、次のプロジェクト ファイルに示すように、(ContainerImageName
古い) または優先する ContainerRepository
を指定してオーバーライドできます。
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-DotNet.ContainerImage-2e40c179-a00b-4cc9-9785-54266210b7eb</UserSecretsId>
<ContainerImageName>dotnet-worker-image</ContainerImageName>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.NET.Build.Containers" Version="7.0.401" />
</ItemGroup>
</Project>
詳細については、「ContainerImageName」を参照してください。
.NET アプリを発行する
.NET アプリをコンテナーとして公開するには、次の dotnet publish コマンドを使用します:
dotnet publish --os linux --arch x64 /t:PublishContainer -c Release
上記の .NET CLI コマンドは、アプリをコンテナーとして発行します。
- OS として Linux をターゲットにする (
--os linux
)。 - x64 アーキテクチャを指定する (
--arch x64
)。 - リリース構成を使用する (
-c Release
)。
重要
コンテナーをローカルにビルドするには、Docker デーモンが実行されている必要があります。 アプリをコンテナーとして公開しようとしたときにそれが実行されていない場合は、次のようなエラーが発生します。
..\build\Microsoft.NET.Build.Containers.targets(66,9): error MSB4018:
The "CreateNewImage" task failed unexpectedly. [..\Worker\DotNet.ContainerImage.csproj]
ヒント
コンテナー化するアプリの種類によっては、コマンド ライン スイッチ (オプション) が異なることがあります。 たとえば、/t:PublishContainer
引数は、Web 以外の .NET アプリ (console
テンプレートや worker
テンプレートなど) にのみ必要です。 Web テンプレートの場合は、/t:PublishContainer
引数を -p:PublishProfile=DefaultContainer
に置き換えます。 詳細については、.NET SDK コンテナー ビルド、問題 #141 を参照してください。
このコマンドを実行すると、次のような出力が生成されます:
Determining projects to restore...
All projects are up-to-date for restore.
DotNet.ContainerImage -> .\Worker\bin\Release\net8.0\linux-x64\DotNet.ContainerImage.dll
DotNet.ContainerImage -> .\Worker\bin\Release\net8.0\linux-x64\publish\
Building image 'dotnet-worker-image' with tags latest on top of base image mcr.microsoft.com/dotnet/aspnet:8.0
Pushed container 'dotnet-worker-image:latest' to Docker daemon
Determining projects to restore...
All projects are up-to-date for restore.
DotNet.ContainerImage -> .\Worker\bin\Release\net7.0\linux-x64\DotNet.ContainerImage.dll
DotNet.ContainerImage -> .\Worker\bin\Release\net7.0\linux-x64\publish\
Building image 'dotnet-worker-image' with tags 1.0.0 on top of base image mcr.microsoft.com/dotnet/aspnet:7.0
Pushed container 'dotnet-worker-image:1.0.0' to Docker daemon
このコマンドは、ワーカー アプリを publish フォルダーにコンパイルし、コンテナーをローカル Docker レジストリにプッシュします。
コンテナー イメージを構成する
生成されるコンテナーの多くの側面は、MSBuild プロパティによって制御できます。 一般に、Dockerfile でコマンドを使用して一部の構成を設定できる場合は、MSBuild を介して同じことを実行できます。
Note
この唯一の例外は RUN
コマンドです。 コンテナーのビルドの方法が理由で、それらはエミュレートできません。 この機能が必要な場合は、Dockerfile を使用してコンテナー イメージをビルドする必要があります。
ContainerArchiveOutputPath
.NET 8 以降では、tar.gz アーカイブとしてコンテナーを直接作成できます。 この機能は、たとえば画像をプッシュする前にスキャン ツールを実行する必要がある場合などワークフローが複雑な場合に便利です。 アーカイブが作成されたら、アーカイブの移動、スキャン、またはローカル Docker ツールチェーンへの読み込みを行うことができます。
アーカイブに発行するには、次に例を示す ContainerArchiveOutputPath
プロパティを dotnet publish
コマンドに追加します。
dotnet publish \
-p PublishProfile=DefaultContainer \
-p ContainerArchiveOutputPath=./images/sdk-container-demo.tar.gz
フォルダー名または特定のファイル名を持つパスを指定できます。 フォルダー名を指定すると、イメージ アーカイブ ファイルに対して生成されるファイル名は $(ContainerRepository).tar.gz
のようになります。 これらのアーカイブには、すべての ContainerImageTags
に対して 1 つのファイルが作成される場合にのみ、それらの中に複数のタグを含めることができます。
コンテナー イメージの名前付けの構成
コンテナー イメージは、特定の名前付け規則に従います。 イメージの名前は複数の部分 (レジストリ、オプションのポート、リポジトリ、オプションのタグとファミリ) で構成されます。
REGISTRY[:PORT]/REPOSITORY[:TAG[-FAMILY]]
たとえば、完全修飾された mcr.microsoft.com/dotnet/runtime:8.0-alpine
イメージ名を考えてみます。
mcr.microsoft.com
がレジストリです (この場合は Microsoft コンテナー レジストリを表します)。dotnet/runtime
がリポジトリです (ただし、これをuser/repository
と見なす人もいます)。8.0-alpine
がタグとファミリです (ファミリは、OS パッケージのあいまいさを解消するのに役立つ省略可能な指定子です)。
次のセクションで説明する一部のプロパティは、生成されたイメージ名の部分の管理に対応しています。 イメージ名とビルド プロパティの関係をマップする次の表を見てみてください。
イメージ名の部分 | MSBuild のプロパティ | サンプル値 |
---|---|---|
REGISTRY[:PORT] |
ContainerRegistry |
mcr.microsoft.com:443 |
PORT |
ContainerPort |
:443 |
REPOSITORY |
ContainerRepository |
dotnet/runtime |
TAG |
ContainerImageTag |
8.0 |
FAMILY |
ContainerFamily |
-alpine |
イメージ名の部分 | MSBuild のプロパティ | サンプル値 |
---|---|---|
REGISTRY[:PORT] |
ContainerRegistry |
mcr.microsoft.com:443 |
PORT |
ContainerPort |
:443 |
REPOSITORY |
ContainerImageName |
dotnet/runtime |
TAG |
ContainerImageTag |
8.0 |
次のセクションでは、生成されたコンテナー イメージを制御するために使用できるさまざまなプロパティについて説明します。
ContainerBaseImage
コンテナーの基本イメージ プロパティによって、イメージの基礎として使用されるイメージが制御されます。 既定では、プロジェクトのプロパティに基づいて次の値が推定されます。
- プロジェクトが自己完結型の場合、
mcr.microsoft.com/dotnet/runtime-deps
イメージが基本イメージとして使用されます。 - プロジェクトが ASP.NET Core プロジェクトの場合、
mcr.microsoft.com/dotnet/aspnet
イメージが基本イメージとして使用されます。 - それ以外の場合は、
mcr.microsoft.com/dotnet/runtime
イメージが基本イメージとして使用されます。
イメージのタグは、選択した TargetFramework
の数値コンポーネントとして推論されます。 たとえば、net6.0
をターゲットとするプロジェクトは、推論された基本イメージの 6.0
タグが作成され、net7.0-linux
プロジェクトではタグが 7.0
使用されます (以下同様)。
ここで値を設定する場合は、必要なタグを含めて、ベースとして使用するイメージの完全修飾名を設定する必要があります。
<PropertyGroup>
<ContainerBaseImage>mcr.microsoft.com/dotnet/runtime:8.0</ContainerBaseImage>
</PropertyGroup>
<PropertyGroup>
<ContainerBaseImage>mcr.microsoft.com/dotnet/runtime:7.0</ContainerBaseImage>
</PropertyGroup>
ContainerFamily
.NET 8 以降では、ContainerFamily
MSBuild プロパティを使用して、アプリの基本イメージとして、Microsoft が提供する別のコンテナー イメージ ファミリを選択できます。 この値を設定すると、選択した TFM 固有のタグの末尾にこの値が追加され、指定されたタグが変更されます。 たとえば、.NET 基本イメージの Alpine Linux バリアントを使用するには、ContainerFamily
を alpine
に設定できます:
<PropertyGroup>
<ContainerFamily>alpine</ContainerFamily>
</PropertyGroup>
上記のプロジェクト構成では、.NET 8 ターゲット アプリの 8.0-alpine
の最終的なタグが生成されます。
このフィールドは自由形式であり、多くの場合、さまざまなオペレーティング システムのディストリビューション、既定のパッケージ構成、または基本イメージに対するその他の変更のフレーバーを選択するために使用できます。 このフィールドは、ContainerBaseImage
が設定されている場合は無視されます。 詳しくは、「.NET コンテナー イメージ」を参照してください。
ContainerRuntimeIdentifier
コンテナー ランタイム識別子プロパティは、ContainerBaseImage が複数のプラットフォームをサポートしている場合に、コンテナーによって使用されるオペレーティング システムとアーキテクチャを制御します。 たとえば、mcr.microsoft.com/dotnet/runtime
イメージは現在、同じタグを基に linux-x64
、linux-arm
、linux-arm64
、win10-x64
イメージのすべてをサポートしているため、それらのいずれのバージョンを使用するのかをツールに指示する手段が必要です。 既定では、コンテナーを発行したときに選択した RuntimeIdentifier
の値に設定されます。 このプロパティを明示的に設定する必要はほとんどありません。その代わりに、dotnet publish
コマンドに -r
オプションを使用します。 選択したイメージが、選択した RuntimeIdentifier
をサポートしていない場合は、イメージがサポートしている RuntimeIdentifiers が説明するエラーが発生します。
このプロパティをまったく使用しないで済むように、常に ContainerBaseImage
プロパティをイメージの完全修飾名 (タグを含む) に設定することができます。
<PropertyGroup>
<ContainerRuntimeIdentifier>linux-arm64</ContainerRuntimeIdentifier>
</PropertyGroup>
.NET でサポートされるランタイム識別子の詳細については、RID カタログを参照してください。
ContainerRegistry
コンテナー レジストリ プロパティによって、宛先レジストリ (新しく作成されたイメージのプッシュ先となる場所) を制御します。 既定ではローカル Docker デーモンにプッシュされますが、リモート レジストリを指定することもできます。 認証を必要とするリモート レジストリを使用する場合は、よく知られた docker login
メカニズムを使用して認証します。 詳細については、「コンテナー レジストリへの認証」を参照してください。 このプロパティを使用する具体例として、次の XML の例を検討します。
<PropertyGroup>
<ContainerRegistry>registry.mycorp.com:1234</ContainerRegistry>
</PropertyGroup>
このツールは、Docker Registry HTTP API V2 をサポートするレジストリへの発行をサポートしています。 これには、次のレジストリが明示的に (おそらく、他の多くのものも暗黙的に) 含まれます。
- Azure Container Registry
- Amazon Elastic Container Registry
- Google Artifact Registry
- Docker Hub
- GitHub Packages
- GitLab でホストされる Container Registry
- Quay.io
これらのレジストリの使用に関する注意事項については、レジストリ固有の注意事項をご覧ください。
ContainerRepository
コンテナー リポジトリは、イメージ自体の名前です、(例: dotnet/runtime
または my-app
)。 既定で、プロジェクトの AssemblyName
が使用されます。
<PropertyGroup>
<ContainerRepository>my-app</ContainerRepository>
</PropertyGroup>
ContainerImageName
コンテナー イメージ名は、イメージ自体の名前を制御します (例: dotnet/runtime
または my-app
)。 既定で、プロジェクトの AssemblyName
が使用されます。
<PropertyGroup>
<ContainerImageName>my-app</ContainerImageName>
</PropertyGroup>
Note
.NET 8 以降では、ContainerImageName
は非推奨とされ、ContainerRepository
が優先されます。
イメージ名は、スラッシュで区切られた 1 つ以上のセグメントで構成され、それぞれに小文字の英数字、ピリオド、アンダースコア、ダッシュのみが含まれ、英字または数字で始まる必要があります。 その他の文字を使用すると、エラーがスローされます。
ContainerImageTag(s)
コンテナー イメージ タグ プロパティは、イメージに対して生成されるタグを制御します。 1 つのタグを指定するには、ContainerImageTag
を使用し、複数のタグには ContainerImageTags
を使用します。
重要
ContainerImageTags
を使用すると、一意のタグごとに 1 つずつ、複数のイメージが作成されます。
タグは、アプリのさまざまなバージョンを参照するためによく使われますが、さまざまなオペレーティング システム ディストリビューションやさまざまな構成を参照することもできます。
.NET 8 以降では、タグが指定されていない場合、既定値は latest
です。
既定で、プロジェクトの Version
がタグ値として使用されます。
既定値をオーバーライドするには、次のいずれかを指定します。
<PropertyGroup>
<ContainerImageTag>1.2.3-alpha2</ContainerImageTag>
</PropertyGroup>
複数のタグを指定するには、複数の TargetFrameworks
を設定するのと同様に、ContainerImageTags
プロパティでセミコロンで区切られたタグのセットを使用します。
<PropertyGroup>
<ContainerImageTags>1.2.3-alpha2;latest</ContainerImageTags>
</PropertyGroup>
タグに使用できるのは、最大 127 文字の英数字、ピリオド、アンダースコア、ダッシュのみです。 それらは英数字またはアンダースコアで始める必要があります。 その他のフォームでは、エラーがスローされます。
Note
ContainerImageTags
を使用する場合、タグは ;
文字で区切られます。 コマンド ラインから dotnet publish
を呼び出す場合 (ほとんどの CI/CD 環境の場合と同様)、値を単一の '
で外部ラップし、"
を二重引用符で囲む必要があります (例: (='"tag-1;tag-2"'
))。 次の dotnet publish
コマンドについて考えてみましょう:
dotnet publish -p ContainerImageTags='"1.2.3-alpha2;latest"'
これにより、次の 2 つのイメージが生成されます。my-app:1.2.3-alpha2
および my-app:latest
。
ヒント
ContainerImageTags
プロパティで問題が発生した場合は、代わりに環境変数 ContainerImageTags
のスコープを設定することを検討してください。
ContainerImageTags='1.2.3;latest' dotnet publish
ContainerLabel
コンテナー ラベルは、メタデータ ラベルをコンテナーに追加します。 ラベルはランタイムでコンテナーに影響しませんが、セキュリティ スキャナーやその他のインフラストラクチャ ツールによって使用されるバージョンと作成メタデータを格納するために多く使用されます。 任意の数のコンテナー ラベルを指定できます。
ContainerLabel
ノードには 2 つの属性があります。
Include
: ラベルのキー。Value
: ラベルの値 (空の場合があります)。
<ItemGroup>
<ContainerLabel Include="org.contoso.businessunit" Value="contoso-university" />
</ItemGroup>
既定で作成されるラベルの一覧については、「既定のコンテナー ラベル」を参照してください。
コンテナーの実行を構成する
コンテナーの実行を制御するには、次の MSBuild プロパティを使用できます。
ContainerWorkingDirectory
コンテナー作業ディレクトリ ノードは、コンテナーの作業ディレクトリ (他のコマンドが実行されていない場合、コマンドが実行されるディレクトリ) を制御します。
既定で、/app
ディレクトリ値が作業ディレクトリとして使用されます。
<PropertyGroup>
<ContainerWorkingDirectory>/bin</ContainerWorkingDirectory>
</PropertyGroup>
ContainerPort
コンテナー ポートは、コンテナーの既知のポートの一覧に TCP ポートまたは UDP ポートを追加します。 これにより、Docker などのコンテナー ランタイムは、これらのポートをホスト マシンに自動的にマップできます。 これは、コンテナーのドキュメントとしてよく使用されますが、自動ポート マッピングを有効にするためにも使用できます。
ContainerPort
ノードには 2 つの属性があります。
Include
: 公開するポート番号。Type
:tcp
に既定値が設定され、有効な値はtcp
またはudp
です。
<ItemGroup>
<ContainerPort Include="80" Type="tcp" />
</ItemGroup>
.NET 8 以降では、いくつかの良く知られている ASP.NET 環境変数に基づいて明示的に指定されていない場合、ContainerPort
が推論されます:
ASPNETCORE_URLS
ASPNETCORE_HTTP_PORTS
ASPNETCORE_HTTPS_PORTS
これらの環境変数が存在する場合、それらの値は解析され、TCP ポート マッピングに変換されます。 これらの環境変数は、基本イメージ (存在する場合) から、または ContainerEnvironmentVariable
項目を介してプロジェクトで定義されている環境変数から読み取られます。 詳細については、「ContainerEnvironmentVariable」を参照してください。
ContainerEnvironmentVariable
コンテナー環境変数ノードにより、コンテナーに環境変数を追加できます。 環境変数は、コンテナー内で実行されているアプリからすぐにアクセスでき、実行中のアプリのランタイム動作を変更するためによく使用されます。
ContainerEnvironmentVariable
ノードには 2 つの属性があります。
Include
: 環境変数の名前。Value
: 環境変数の値。
<ItemGroup>
<ContainerEnvironmentVariable Include="LOGGER_VERBOSITY" Value="Trace" />
</ItemGroup>
詳細については、「.NET 環境変数」を参照してください。
コンテナー コマンドの構成
既定では、コンテナー ツールは、アプリに対して生成された AppHost バイナリ (アプリが AppHost を使用している場合) または dotnet
コマンドとアプリの DLL を使用してアプリを起動します。
ただし、ContainerAppCommand
、ContainerAppCommandArgs
、ContainerDefaultArgs
、ContainerAppCommandInstruction
の組み合わせを使用して、アプリの実行方法を制御できます。
これらの異なる構成ポイントは、異なる基本イメージがコンテナー ENTRYPOINT
と COMMAND
プロパティの異なる組み合わせを使用し、それらすべてをサポートできるようにするために存在します。 既定値はほとんどのアプリで使用できる必要がありますが、アプリの起動動作をカスタマイズする場合は、次の操作を行う必要があります:
- 実行するバイナリを識別し、
ContainerAppCommand
として設定する - アプリケーションを実行するために必要な引数を特定し、
ContainerAppCommandArgs
として設定する - 省略可能な引数 (存在する場合) を特定し、ユーザーによってオーバーライドし、
ContainerDefaultArgs
として設定できます ContainerAppCommandInstruction
をDefaultArgs
に設定する
詳細については、次の構成項目を参照してください。
ContainerAppCommand
アプリ コマンド構成項目は、アプリの論理エントリ ポイントです。 ほとんどのアプリでは、これはアプリ用に生成された実行可能バイナリである AppHost です。 アプリで AppHost が生成されない場合、このコマンドは通常は dotnet <your project dll>
です。 これらの値は、基本コンテナー内の任意の ENTRYPOINT
の後、または ENTRYPOINT
が定義されていない場合は直接適用されます。
ContainerAppCommand
構成には、entrypoint コマンドで使用するコマンド、オプション、または引数を表す 1 つの Include
プロパティがあります:
<ItemGroup Label="ContainerAppCommand Assignment">
<!-- This is how you would start the dotnet ef tool in your container -->
<ContainerAppCommand Include="dotnet" />
<ContainerAppCommand Include="ef" />
<!-- This shorthand syntax means the same thing, note the semicolon separating the tokens. -->
<ContainerAppCommand Include="dotnet;ef" />
</ItemGroup>
ContainerAppCommandArgs
このアプリ コマンド引数構成項目は、ContainerAppCommand
に適用する必要があるアプリの論理的に必要な員数を表します。 既定では、アプリには何も生成されません。 存在する場合、引数は実行時にコンテナーに適用されます。
ContainerAppCommandArgs
構成には、ContainerAppCommand
コマンドに適用するオプションまたは引数を表す 1 つの Include
プロパティがあります。
<ItemGroup>
<!-- Assuming the ContainerAppCommand defined above,
this would be the way to force the database to update.
-->
<ContainerAppCommandArgs Include="database" />
<ContainerAppCommandArgs Include="update" />
<!-- This is the shorthand syntax for the same idea -->
<ContainerAppCommandArgs Include="database;update" />
</ItemGroup>
ContainerDefaultArgs
この既定の引数構成項目は、アプリのユーザーがオーバーライドできる引数を表します。 アプリが簡単に開始でき、しかし簡単にカスタマイズできるようアプリを実行するための既定値を指定するための良い方法です。
ContainerDefaultArgs
構成には、ContainerAppCommand
コマンドに適用するオプションまたは引数を表す 1 つの Include
プロパティがあります。
<ItemGroup>
<!-- Assuming the ContainerAppCommand defined above,
this would be the way to force the database to update.
-->
<ContainerDefaultArgs Include="database" />
<ContainerDefaultArgs Include="update" />
<!-- This is the shorthand syntax for the same idea -->
<ContainerDefaultArgs Include="database;update" />
</ItemGroup>
ContainerAppCommandInstruction
アプリ コマンド命令の構成は、ContainerEntrypoint
、ContainerEntrypointArgs
、ContainerAppCommand
、ContainerAppCommandArgs
、および ContainerDefaultArgs
を組み合わせて、コンテナーで実行される最終的なコマンドを形成する方法を制御するのに役立ちます。 これは、基本イメージに存在するかどうか ENTRYPOINT
によって大きく異なります。 このプロパティは、次の 3 つの値のいずれかを受け取ります: "DefaultArgs"
"Entrypoint"
または "None"
。
Entrypoint
:- このモードでは、エントリ ポイントは
ContainerAppCommand
、ContainerAppCommandArgs
、およびContainerDefaultArgs
により定義されます。
- このモードでは、エントリ ポイントは
None
:- このモードでは、エントリ ポイントは
ContainerEntrypoint
、ContainerEntrypointArgs
、およびContainerDefaultArgs
です。
- このモードでは、エントリ ポイントは
DefaultArgs
:- これは最も複雑なモードです。
ContainerEntrypoint[Args]
項目が存在しない場合は、ContainerAppCommand[Args]
とContainerDefaultArgs
がエントリポイントとコマンドの作成に使用されます。 完全に制御できるように、dotnet
または/usr/bin/dotnet
にハードコーディングされた基本イメージの基本イメージ暗号化がスキップされます。 ContainerEntrypoint
とContainerAppCommand
の両方が存在する場合、ContainerEntrypoint
がエントリ ポイントになり、ContainerAppCommand
がコマンドになります。
- これは最も複雑なモードです。
Note
.NET 8 の時点で、ContainerEntrypoint
構成項目と ContainerEntrypointArgs
構成項目は非推奨になりました。
重要
これは、上級ユーザー向けであり、ほとんどのアプリはエントリポイントをこの程度にカスタマイズする必要はありません。 詳細情報を知りたい場合や、シナリオにユース ケースを指定する場合は、「GitHub: .NET SDK コンテナービルドのディスカッション」を参照してください。
ContainerUser
user configuration プロパティは、コンテナーが実行される既定のユーザーを制御します。 これは、セキュリティのベスト プラクティスである非ルート ユーザーとしてコンテナーを実行するためによく使用されます。 この構成には注意する必要がある制約がいくつかあります:
- ユーザー名、Linux ユーザー ID、グループ名、Linux グループ ID、
username:groupname
、その他の ID バリアントなど、さまざまな形式を取りえます。 - 指定されたユーザーまたはグループがイメージに存在するという検証はありません。
- ユーザーを変更すると、特にファイル システム のアクセス許可などに関して、アプリの動作を変更できます。
このフィールドの既定値は、プロジェクト TFM とターゲット オペレーティング システムによって異なります:
- .NET 8 以降を対象とし、Microsoft ランタイム イメージを使用している場合は、次のようにします:
- Linux では、ルートレス ユーザー
app
が使用されます (ただし、そのユーザー ID によって参照されます) - Windows では、ルートレス ユーザー
ContainerUser
が使用されます
- Linux では、ルートレス ユーザー
- それ以外の場合、既定値
ContainerUser
は使用されません
<PropertyGroup>
<ContainerUser>my-existing-app-user</ContainerUser>
</PropertyGroup>
ヒント
APP_UID
環境変数は、コンテナー内のユーザー情報を設定するために使用されます。 この値は、基本イメージで定義されている環境変数から取得 (Microsoft .NET イメージ同様) することも、ContainerEnvironmentVariable
構文を使用して自分で設定することもできます。
ただし、ContainerEntrypoint
と ContainerEntrypointArgs
を使用して、アプリの実行方法を制御できます。
ContainerEntrypoint
コンテナー エントリ ポイントを使用して、コンテナーの ENTRYPOINT
をカスタマイズできます。これは、コンテナーの起動時に呼び出される実行可能ファイルです。 既定では、アプリ ホストを作成するビルドの場合、それが ContainerEntrypoint
として設定されます。 実行可能ファイルを作成しないビルドの場合、dotnet path/to/app.dll
は ContainerEntrypoint
として使用されます。
ContainerEntrypoint
ノードには 1 つの属性があります。
Include
:ContainerEntrypoint
コマンドで使用するコマンド、オプション、または引数。
たとえば、次のサンプル .NET プロジェクト項目グループを考えます。
<ItemGroup Label="Entrypoint Assignment">
<!-- This is how you would start the dotnet ef tool in your container -->
<ContainerEntrypoint Include="dotnet" />
<ContainerEntrypoint Include="ef" />
<!-- This shorthand syntax means the same thing.
Note the semicolon separating the tokens. -->
<ContainerEntrypoint Include="dotnet;ef" />
</ItemGroup>
ContainerEntrypointArgs
コンテナー エントリ ポイント args ノードは、ContainerEntrypoint
に提供される既知の引数を制御します。 これは、ContainerEntrypoint
がユーザーがそのままで使用したいと考える可能性があるプログラムである場合に使用する必要があります。 既定で、ContainerEntrypointArgs
は自動的に作成されません。
ContainerEntrypointArg
ノードには 1 つの属性があります。
Include
:ContainerEntrypoint
コマンドに適用するオプションまたは引数。
次の .NET プロジェクト項目グループの例を考えます。
<ItemGroup>
<!-- Assuming the ContainerEntrypoint defined above,
this would be the way to update the database by
default, but let the user run a different EF command. -->
<ContainerEntrypointArgs Include="database" />
<ContainerEntrypointArgs Include="update" />
<!-- This is the shorthand syntax for the same idea -->
<ContainerEntrypointArgs Include="database;update" />
</ItemGroup>
既定のコンテナー ラベル
ラベルは、コンテナー イメージに関する一貫性のあるメタデータを提供するためによく使用されます。 このパッケージには、生成されたイメージの保守性を向上させるために、いくつかの既定のラベルが用意されています。
org.opencontainers.image.created
は現在の UTCDateTime
の ISO 8601 形式に設定されます。
詳細については、「既存のラベル インフラストラクチャの上に従来のラベルを実装する」を参照してください。
リソースをクリーンアップする
この記事では、.NET ワーカーをコンテナー イメージとして公開しました。 必要に応じて、このリソースを削除します。 インストールされているイメージの一覧を表示するには、docker images
コマンドを使います。
docker images
次の出力例を考えてみましょう。
REPOSITORY TAG IMAGE ID CREATED SIZE
dotnet-worker-image 1.0.0 25aeb97a2e21 12 seconds ago 191MB
ヒント
イメージ ファイルは大きくなることがあります。 普通、アプリのテスト中および開発中に作成した一時的なコンテナーは削除します。 通常、ランタイムがインストールされた基本イメージは、そのランタイムを基にして他のイメージをビルドする予定がある場合は、残しておきます。
イメージを削除するには、イメージ ID をコピーし、docker image rm
コマンドを実行します。
docker image rm 25aeb97a2e21
次のステップ
.NET