在 Visual Studio 中自訂 Docker 容器

將 Docker 支援新增至專案時,您可以編輯 Visual Studio 產生的 Dockerfile 來自訂容器映像。 無論您是從 Visual Studio IDE 建置自訂容器,還是設定命令列組建,您都必須知道 Visual Studio 如何使用 Dockerfile 來建置專案。 您必須知道這類詳細資料,因為基於效能考量,Visual Studio 會遵循在 Dockerfile 中不明顯的特殊程序來建置和執行容器化應用程式。

假設您想要在 Dockerfile 中進行變更,並在偵錯和生產容器中查看結果。 在此情況下,您可以在 Dockerfile 中新增命令來修改第一個階段 (通常是 base)。 請參閱修改用於偵錯和生產的容器映像。 但是,如果您想要只在偵錯時進行變更,而不是在生產時,則應該建立另一個階段,並使用 DockerfileFastModeStage 建置設定告訴 Visual Studio 使用該階段來進行偵錯建置。 請參閱僅修改用於偵錯的容器映像

本文將詳細說明 Visual Studio 的容器化應用程式建置程序,然後包含如何修改 Dockerfile 以影響偵錯和生產建置 (或僅影響偵錯) 的資訊。

Visual Studio 中的 Dockerfile 建置

注意

本節說明選擇 Dockerfile 容器建置類型時,Visual Studio 所使用的容器建置流程。 如果您使用 .NET SDK 建置類型,自訂選項會有所不同,而本節中的資訊也不適用。 請另行參閱使用 dotnet publish 將 .NET 應用程式容器化,並使用自訂容器中所述的屬性來設定容器建置流程。

多階段建置

當 Visual Studio 建置不使用 Docker 容器的專案時,Visual Studio 會在本機電腦上叫用 MSBuild,並在本機解決方案資料夾下的資料夾 (通常是 bin) 中產生輸出檔案。 不過,針對容器化專案,建置程序會考慮 Dockerfile 的指示來建置容器化應用程式。 Visual Studio 使用的 Dockerfile 分成多個階段。 此程序依賴 Docker 的多階段建置功能。

多階段建置功能有助於讓建置容器的程序更有效率,藉由允許容器只包含應用程式在執行階段時所需的位元,來讓容器變得更小。 多階段建置會用於 .NET Core 專案,而不是用於 .NET Framework 專案。

多階段建置可讓容器映像在產生中繼映像的階段中建立。 例如,以典型 Dockerfile 為例。 在 Visual Studio 產生的 Dockerfile 中,第一個階段稱為 base,不過工具不需要該名稱。

# This stage is used when running from VS in fast mode (Default for Debug configuration)
FROM mcr.microsoft.com/dotnet/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

Dockerfile 中的行會從 Microsoft Container Registry (mcr.microsoft.com) 的 ASP.NET 映像開始,並建立公開連接埠 80 和 443 的中繼映像 base,然後將工作目錄設定為 /app

下一個階段是 build,如下所示:

# This stage is used to build the service project
FROM mcr.microsoft.com/dotnet/sdk:3.1-buster-slim AS build
WORKDIR /src
COPY ["WebApplication43/WebApplication43.csproj", "WebApplication43/"]
RUN dotnet restore "WebApplication43/WebApplication43.csproj"
COPY . .
WORKDIR "/src/WebApplication43"
RUN dotnet build "WebApplication43.csproj" -c Release -o /app/build

您可以看到 build 階段從登錄的不同原始映像開始 (sdk,而不是 aspnet),並不是從基底繼續。 sdk 映像具有所有的建置工具,因此比只包含執行階段元件的 aspnet 映像要大得多。 當您查看 Dockerfile 的其餘部分時,使用不同映像的原因會更清楚:

# This stage is used to publish the service project to be copied to the final stage
FROM build AS publish
RUN dotnet publish "WebApplication43.csproj" -c Release -o /app/publish

# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebApplication43.dll"]

最後階段會再次從 base開始,並包含 COPY --from=publish 開始,以將已發佈的輸出複製到最終映像。 此程序可讓最終映像變得更小,因為其不需要包含 sdk 映像中的所有建置工具。

下表摘要說明 Visual Studio 所建立之一般 Dockerfile 中使用的階段:

階段 描述
base 建立用於發佈已建置應用程式的基礎執行階段映像。 需要在執行階段提供的設定位於此處,例如連接埠和環境變數。 在快速模式中從 VS 執行時,會使用此階段 (偵錯組態的預設值)。
build 此專案會在此階段中建置。 使用 .NET SDK 基礎映像,其中包含建置專案所需的元件。
publish 此階段衍生自建置階段,會發佈您的專案,並且專案將複製到最終階段。
final 這個階段會設定如何啟動應用程式,並在生產環境中或在一般模式中從 VS 執行時使用 (不使用偵錯組態時的預設值)。
aotdebug 當從 VS 啟動以支援一般模式偵錯時,此階段會做為最後階段的基礎 (不使用偵錯組態時的預設值)。

注意

只有 Linux 容器才支援 aotdebug 階段。 如果在專案上啟用原生預先 (AOT) 部署,則會在 Visual Studio 2022 17.11 和更新版本中使用此階段。

專案暖身

專案暖身是指對專案選取 Docker 設定檔時 (也就是載入專案或新增 Docker 支援時),發生的一系列步驟,目的是改善後續執行 (F5Ctrl+F5) 的效能。 此行為可在 [工具]>[選項]>[容器工具] 底下設定。 以下是在背景中執行的工作:

  • 檢查 Docker Desktop 是否已安裝並執行。
  • 確定 Docker Desktop 已設定為與專案相同的作業系統。
  • 在 Dockerfile 的第一個階段中提取映像 (大部分 Dockerfile 中的 base 階段)。
  • 建置 Dockerfile 並啟動容器。

熱身只會在 [快速] 模式中發生,因此執行中的容器具有應用程式資料夾磁碟區掛接。 這表示對應用程式所做的任何變更都不會使容器失效。 此行為可大幅改善偵錯效能,並減少長時間執行工作的等候時間,例如提取大型映像時。

啟用詳細的容器工具記錄

基於診斷目的,您可以啟用特定容器工具記錄。 您可以藉由設定特定環境變數來啟用這些記錄。 對於單一容器專案,環境變數是 MS_VS_CONTAINERS_TOOLS_LOGGING_ENABLED,然後記錄於 %tmp%\Microsoft.VisualStudio.Containers.Tools 中。 針對 Docker Compose 專案,其為 MS_VS_DOCKER_TOOLS_LOGGING_ENABLED,然後記錄於 %tmp%\Microsoft.VisualStudio.DockerCompose.Tools 中。

警告

啟用記錄功能,且使用權杖 Proxy 進行 Azure 驗證時,驗證認證可以記錄為純文字。 請參閱設定 Azure 驗證

下一步

了解如何使用 Dockerfile 階段來自訂用於偵錯和生產環境的圖像,例如,如何只在偵錯時,才在圖像上安裝工具。 請參閱設定容器圖像以進行偵錯