使用 dotnet publish 將 .NET 應用程式容器化

容器有許多功能和優點,例如不可變的基礎結構、提供可攜式結構,以及啟用可擴縮性。 映像可用來為您的本機開發環境、私人雲端,或公用雲端建立容器。 在本教學課程中,您將了解如何使用 dotnet publish 命令以將 .NET 應用程式容器化。

必要條件

安裝下列先決條件:

除了這些必要條件之外,建議您熟悉 .NET 中的背景工作角色服務

建立 .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 的新資料夾,並產生背景工作服務,而此服務會在執行時每秒記錄一則訊息。 從終端機工作階段中,變更目錄,並導覽至 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 套件

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 命令會將應用程式發佈為容器:

  • 將 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]

提示

根據您要容器化的應用程式類型,命令列參數 (選項) 可能會不同。 例如,非 Web .NET 應用程式 (例如 consoleworker 範本) 只需要 /t:PublishContainer 引數。 針對 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 執行相同的動作。

注意

唯一的例外是 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 建立單一檔案。

容器映像命名設定

容器映像會遵循特定的命名慣例。 映像的名稱是由數個組件、登錄、選擇性連接埠、存放庫和選擇性標記及系列所組成。

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 container images (部分機器翻譯)

ContainerRuntimeIdentifier

如果您的 ContainerBaseImage 支援多個平台,則容器執行階段識別碼屬性可控制容器所使用的作業系統和結構。 例如,mcr.microsoft.com/dotnet/runtime 映像目前支援全都位於相同標籤後面的 linux-x64linux-armlinux-arm64win10-x64 映像,因此需要方式,將您想要使用的其中哪個版本告知工具。 根據預設,這會設定為您在發佈容器時所選擇的 RuntimeIdentifier 的值。 這個屬性很少需要明確進行設定,而是使用 dotnet publish 命令的 -r 選項。 如果您所選擇的映像不支援您所選擇的 RuntimeIdentifier,則會導致描述映像所支援 RuntimeIdentifier 的錯誤。

您一律可以將 ContainerBaseImage 屬性設定為完整映像名稱 (包括標籤),以完全避免需要使用此屬性。

<PropertyGroup>
    <ContainerRuntimeIdentifier>linux-arm64</ContainerRuntimeIdentifier>
</PropertyGroup>

如需有關 .NET 所支援之執行階段識別碼的詳細資訊,請參閱 RID 目錄

ContainerRegistry

容器登錄屬性可控制目的地登錄,而目的地登錄是將新建立映像推送至其中的位置。 根據預設,會將其推送至本機 Docker 精靈,但您也可以指定遠端登錄。 使用需要驗證的遠端登錄時,您可以使用已知 docker login 機制來進行驗證。 如需更多詳細資料,請參閱向容器登錄進行驗證以取得更多詳細資料。 如需使用此屬性的具體範例,請考慮下列 XML 範例:

<PropertyGroup>
    <ContainerRegistry>registry.mycorp.com:1234</ContainerRegistry>
</PropertyGroup>

此工具支援發佈至任何支援 Docker 登錄 HTTP API V2 的登錄。 這明確包括下列登錄 (而且可能隱含地包括更多):

如需使用這些登錄的附註,請參閱登錄特定附註

ContainerRepository

容器存放庫是映像本身的名稱,例如 dotnet/runtimemy-app。 根據預設,會使用專案的 AssemblyName

<PropertyGroup>
    <ContainerRepository>my-app</ContainerRepository>
</PropertyGroup>

ContainerImageName

容器映像名稱會控制映像本身的名稱,例如 dotnet/runtimemy-app。 根據預設,會使用專案的 AssemblyName

<PropertyGroup>
    <ContainerImageName>my-app</ContainerImageName>
</PropertyGroup>

注意

從 .NET 8 開始, ContainerImageName 已被取代為 ContainerRepository

映像名稱是由一或多個斜線分隔的區段所組成,而每個區段只能包含小寫英數位元、句號、底線和破折號,而且開頭必須是字母或數字。 任何其他字元都會導致擲回錯誤。

ContainerImageTag(s)

容器映像標籤屬性可控制針對映像所產生的標籤。 指定單一標記使用 ContainerImageTag,並針對多個標記,使用 ContainerImageTags

重要

當您使用 ContainerImageTags 時,最後會有多個映像,每個唯一標記一個。

標記通常會用於參考不同版本的應用程式,但它們也可以參考不同的作業系統散發套件,或甚至是不同的設定。

從 .NET 8 開始,未提供標記時,預設值為 latest

根據預設,會使用專案的 Version 作為標籤值。

若要覆寫預設值,請指定下列任一項:

<PropertyGroup>
    <ContainerImageTag>1.2.3-alpha2</ContainerImageTag>
</PropertyGroup>

若要指定多個標籤,請在 ContainerImageTags 屬性中使用以分號分隔的標記集,而這與設定多個 TargetFrameworks 類似:

<PropertyGroup>
    <ContainerImageTags>1.2.3-alpha2;latest</ContainerImageTags>
</PropertyGroup>

標籤最多只能包含 127 個英數字元、句點、底線和破折號。 其開頭必須是英數字元或底線。 任何其他表單都會導致擲回錯誤。

注意

使用 ContainerImageTags 時,標記會以 ; 字元分隔。 如果您要從命令行呼叫 dotnet publish (如同大部分 CI/CD 環境的情況),您需要將值外部包裝在單一 ' 並以雙引號 " 內部包裝,例如 (='"tag-1;tag-2"')。 請考慮下列 dotnet publish 命令:

dotnet publish -p ContainerImageTags='"1.2.3-alpha2;latest"'

這會導致產生兩個映像:my-app:1.2.3-alpha2my-app:latest

提示

如果您遇到 ContainerImageTags 屬性的問題,請考慮改用環境變數 ContainerImageTags 的範圍:

ContainerImageTags='1.2.3;latest' dotnet publish

ContainerLabel

容器標籤會將中繼資料標籤新增至容器。 標籤不會影響執行階段的容器,但通常會用於儲存版本和製作中繼資料,以供安全性掃描器和其他基礎結構工具使用。 您可以指定任意數目的容器標籤。

ContainerLabel 節點有兩個屬性:

  • 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 節點有兩個屬性:

  • Include:要公開的連接埠號碼。
  • Type:預設為 tcp,有效值為 tcpudp
<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 節點有兩個屬性:

  • Include:環境變數的名稱。
  • Value:環境變數的值。
<ItemGroup>
  <ContainerEnvironmentVariable Include="LOGGER_VERBOSITY" Value="Trace" />
</ItemGroup>

如需詳細資訊,請參閱 .NET 環境變數

設定容器命令

根據預設,容器工具會使用應用程式產生的 AppHost 二進位來啟動您的應用程式(如果您的應用程式使用 AppHost),或 dotnet 命令加上您應用程式的 DLL。

不過,您可以使用 ContainerAppCommandContainerAppCommandArgsContainerDefaultArgsContainerAppCommandInstruction 的組合來控制應用程式的執行方式。

這些不同的設定點存在,因為不同的基礎映像會使用不同的容器 ENTRYPOINTCOMMAND 屬性的組合,而且您想要能夠支援所有這些組合。 預設值應該適用於大部分的應用程式,但如果您想要自訂應用程式啟動行為,您應該:

  • 識別要執行的二進位,並將其設定為 ContainerAppCommand
  • 識別應用程式執行所需的引數並將其設定為 ContainerAppCommandArgs
  • 識別哪些引數 (如有) 為選擇性的,而且可由使用者覆寫,並將其設定為 ContainerDefaultArgs
  • ContainerAppCommandInstruction (API 定義來源) 設定為 [DefaultArgs]

如需詳細資訊,請參閱下列設定項目。

ContainerAppCommand

應用程式命令設定項目是您應用程式的邏輯進入點。 對於大部分的應用程式而言,這是 AppHost,這是應用程式產生的可執行檔二進位。 如果您的應用程式不會產生 AppHost,則此命令通常為 dotnet <your project dll>。 這些值會在基礎容器中的任何 ENTRYPOINT 之後套用,或在未定義 ENTRYPOINT 時直接套用。

ContainerAppCommand 設定具有單一 Include 屬性,其會代表在 entrypoint 命令中使用的命令、選項或引數:

<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 設定具有單一 Include 屬性,代表要套用至 ContainerAppCommand 命令的選項或引數。

<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 設定具有單一 Include 屬性,代表要套用至 ContainerAppCommand 命令的選項或引數。

<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

應用程式命令指令設定可協助控制 ContainerEntrypointContainerEntrypointArgsContainerAppCommandContainerAppCommandArgsContainerDefaultArgs 的組合方式,以形成在容器中執行的最終命令。 這很大部分會依據基礎映像中是否存在 ENTRYPOINT 而定。 此屬性會採用下列三個值之一:"DefaultArgs""Entrypoint""None"

  • Entrypoint
    • 在此模式中,進入點會由 ContainerAppCommandContainerAppCommandArgsContainerDefaultArgs 定義。
  • None
    • 在此模式中,進入點會由 ContainerEntrypointContainerEntrypointArgsContainerDefaultArgs 定義。
  • DefaultArgs
    • 這是最複雜的模式,如果沒有任何 ContainerEntrypoint[Args] 項目存在,則 ContainerAppCommand[Args]ContainerDefaultArgs 會用於建立進入點和命令。 已硬式編碼為 dotnet 或略過 /usr/bin/dotnet 的基礎映像的基礎映射進入點,以便您可以完全控制。
    • 如果 ContainerEntrypointContainerAppCommand 都存在,則 ContainerEntrypoint 會成為進入點,而 ContainerAppCommand 則會成為命令。

注意

ContainerEntrypointContainerEntrypointArgs 設定項目從 .NET 8 起已被取代。

重要

這適用於進階使用者,大部分的應用程式都不應該需要將其進入點自訂到這個程度。 如需詳細資訊,而且如果您想要提供您案例的使用案例,請參閱 GitHub:.NET SDK 容器組建討論

ContainerUser

使用者設定屬性會控制容器執行時的預設使用者。 這通常會用於以非根使用者身分執行容器,這是安全性的最佳做法。 此設定有幾個限制式需要注意:

  • 其可採用各種形式:使用者名稱、Linux 使用者識別碼、群組名稱、Linux 群組識別碼、username:groupname 以及其他識別碼變體。
  • 無法驗證指定的使用者或群組是否存在於映像上。
  • 變更使用者可以改變應用程式的行為,尤其是在檔案系統權限等方面。

此欄位的預設值會因專案 TFM 與目標作業系統而異:

  • 如果您要以 .NET 8 或更新版本為目標,並使用 Microsoft 執行階段映像,則:
    • 在 Linux 上使用無根使用者 app (雖然參考依據是其使用者識別碼)
    • 在 Windows 上使用無根使用者 ContainerUser
  • 否則,不會使用任何預設值 ContainerUser
<PropertyGroup>
  <ContainerUser>my-existing-app-user</ContainerUser>
</PropertyGroup>

提示

APP_UID 環境變數可用於在您的容器中設定使用者資訊。 此值可能來自基礎映像中所定義的環境變數 (就像 Microsoft .NET 映像所做的一樣),也可以透過 ContainerEnvironmentVariable 語法自行設定。

不過,您可以使用 ContainerEntrypointContainerEntrypointArgs 控制應用程式的執行方式。

ContainerEntrypoint

容器進入點可以用來自訂容器的 ENTRYPOINT,而這是啟動容器時所呼叫的可執行檔。 根據預設,針對建立應用程式主機的組建,這會設定為 ContainerEntrypoint。 針對未建立可執行檔的組建,會使用 dotnet path/to/app.dll 作為 ContainerEntrypoint

ContainerEntrypoint 節點具有單一屬性:

  • 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

容器進入點引數節點可控制提供給 ContainerEntrypoint 的預設引數。 ContainerEntrypoint 是使用者可能想要自行使用的程式時,應該使用此項目。 根據預設,不會代表您建立 ContainerEntrypointArgs

ContainerEntrypointArg 節點具有單一屬性:

  • 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 設定為目前 UTC DateTime 的 ISO 8601 格式。

如需詳細資訊,請參閱在現有標籤基礎結構上實作傳統標籤

清除資源

在本文中,您已將 .NET 背景工作角色發佈為容器映像。 您可以視需要刪除此資源。 使用 docker images 命令查看已安裝映像的清單。

docker images

請考慮下列範例輸出:

REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
dotnet-worker-image   1.0.0     25aeb97a2e21   12 seconds ago   191MB

提示

映像檔可能很大。 一般而言,會移除您在測試及開發應用程式時所建立的暫存容器。 如果您打算根據已安裝的執行階段建置其他映像,您通常會使用該執行階段來保存基底映像。

若要刪除映像,請複製映像識別碼,然後執行 docker image rm 命令:

docker image rm 25aeb97a2e21

下一步