自訂容器映像以進行偵錯
注意
本節說明當您選擇 Dockerfile 容器組建類型時,如何自定義 Docker 容器。 如果您使用 .NET SDK 組建類型,自定義選項會有所不同,而且本節中大部分的資訊都不適用。 相反地,請參閱使用 dotnet publish 將 .NET 應用程式容器化。
當您在 Debug 組態中建置時,Visual Studio 會進行數個優化,以協助容器化專案的建置程式效能。 容器化應用程式的建置程式並不像直接遵循 Dockerfile 中所述的步驟一樣簡單。 在容器中建置的速度比在本機計算機上建置慢。 因此,當您在 Debug 配置中進行建置時,Visual Studio 實際上是在本地機器上建置您的專案,然後透過磁碟區掛載將輸出資料夾共享到容器中。 啟用此優化的組建稱為 快速 模式組建。
在 快速 模式中,Visual Studio 會使用自變數呼叫 docker build
,告知 Docker 只建置 Dockerfile 中的第一個階段(通常是 base
階段)。 您可以藉由設定 MSBuild 屬性 DockerfileFastModeStage
來變更該屬性,如 Container Tools MSBuild 屬性中所述。 Visual Studio 會處理處理程式的其餘部分,而不考慮 Dockerfile 的內容。 因此,當您修改 Dockerfile 時,例如自定義容器環境或安裝其他相依性,您應該將修改放在第一個階段。 不會執行 Dockerfile build
、publish
或 final
階段中的任何自定義步驟。
只有在您在 Debug 組態中建置時,才會發生此效能優化。 在 Release 組態中,組建會在 Dockerfile 中指定的容器中發生。 您可以將項目檔中的 ContainerDevelopmentMode
設定為 Fast,以啟用發行組態的這個行為:
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<ContainerDevelopmentMode>Fast</ContainerDevelopmentMode>
</PropertyGroup>
如果您想要停用所有組態的效能優化,並以 Dockerfile 指定的形式建置,請將 ContainerDevelopmentMode 属性設定為 項目檔中的 Regular,如下所示:
<PropertyGroup>
<ContainerDevelopmentMode>Regular</ContainerDevelopmentMode>
</PropertyGroup>
若要還原效能優化,請從項目檔中移除 屬性。
當您開始偵錯時(F5),如果可能的話,就會重複使用先前啟動的容器。 如果您不想重複使用先前的容器,可以使用 Rebuild 或 Visual Studio 中的 Clean 命令,強制 Visual Studio 使用全新的容器。
執行除錯程式的程式取決於專案和容器作業系統的類型:
場景 | 調試進程 |
---|---|
.NET Core 應用程式 (Linux 容器) | Visual Studio 會下載 vsdbg ,並將其對應至容器,然後使用您的程式和自變數呼叫它(也就是 dotnet webapp.dll ),然後調試程式附加至進程。 |
.NET Core 應用程式 (Windows 容器) | Visual Studio 會使用 onecoremsvsmon ,並將其對應至容器、將它當做進入點執行,然後 Visual Studio 連接到它並附加至程式。 |
.NET Framework 應用程式 | Visual Studio 會使用 msvsmon ,並將其對應至容器、在 Visual Studio 可以連線到容器的進入點中執行它,並附加至程式。 這類似於您通常會在另一部計算機或虛擬機上設定遠端偵錯的方式。 |
如需瞭解 vsdbg.exe
的資訊,請參閱使用 Visual Studio 在 Linux 和 OS X 上對 .NET Core 進行越野偵錯的。
修改容器映像以進行偵錯和生產
若要修改用於偵錯和生產環境的容器映像,請修改 base
階段。 將自訂配置新增至 Dockerfile 基底階段部分,通常是 Dockerfile 的第一個部分。 如需 Dockerfile 命令的相關信息,請參閱 Docker 檔中的 Dockerfile 參考。
# This stage is used when running from VS in fast mode (Default for Debug configuration)
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
# <add your commands here>
# This stage is used to build the service project
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["WebApplication3/WebApplication3.csproj", "WebApplication3/"]
RUN dotnet restore "WebApplication3/WebApplication3.csproj"
COPY . .
WORKDIR "/src/WebApplication3"
RUN dotnet build "WebApplication3.csproj" -c Release -o /app/build
# This stage is used to publish the service project to be copied to the final stage
FROM build AS publish
RUN dotnet publish "WebApplication3.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", "WebApplication3.dll"]
僅修改容器映像以進行偵錯
您可以透過某些方式自定義容器,以協助偵錯,例如為診斷目的安裝某些專案,而不會影響生產組建。
若要只修改容器以進行偵錯,請建立階段,然後使用 MSBuild 屬性 DockerfileFastModeStage
指示 Visual Studio 在偵錯時使用自定義階段。 如需 Dockerfile 命令的相關信息,請參閱 Docker 檔中的 Dockerfile 參考。
注意
這裡的指示適用於單一容器案例。 您也可以使用 Docker Compose 對多個容器執行相同的動作,但 Docker Compose 所需的技術稍有不同。 例如,階段是由 dockercompose.debug.yml
檔案中的設定所控制。
在下列範例中,我們會安裝套件 procps-ng
,但僅限於偵錯模式。 此套件提供 Visual Studio 所需的命令 pidof
(在以 .NET 5 和更早版本為目標時),但此命令不包含在此處使用的 Mariner 映像中。 我們用於快速模式偵錯的階段是 debug
,這是這裡定義的自定義階段。 快速模式階段不需要繼承自 build
或 publish
階段,它可以直接繼承自 base
階段,因為Visual Studio會掛接包含執行應用程式所需的所有專案磁碟區,如本文稍早所述。
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
# This stage is used when running from VS in fast mode (Default for Debug configuration)
FROM mcr.microsoft.com/dotnet/aspnet:6.0-cbl-mariner2.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM base AS debug
RUN tdnf install procps-ng -y
# This stage is used to build the service project
FROM mcr.microsoft.com/dotnet/sdk:6.0-cbl-mariner2.0 AS build
WORKDIR /src
COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"]
RUN dotnet restore "WebApplication1/WebApplication1.csproj"
COPY . .
WORKDIR "/src/WebApplication1"
RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build
# This stage is used to publish the service project to be copied to the final stage
FROM build AS publish
RUN dotnet publish "WebApplication1.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", "WebApplication1.dll"]
在項目檔中,新增此設定,以告訴Visual Studio在偵錯時使用您的自定義階段 debug
。
<PropertyGroup>
<!-- other property settings -->
<DockerfileFastModeStage>debug</DockerfileFastModeStage>
</PropertyGroup>
使用 AOT 部署自定義偵錯映像
為了支援原生 AOT 部署,會安裝 GNU 調試程式 (GDB),但只會安裝在偵錯時所使用的映射上,而不是最終運行時間映像。 Dockerfile 包含組建自變數 LAUNCHING_FROM_VS
,它可以 true
或 false
。 如果 true
,則會使用 aotdebug
階段,也就是安裝 GDB 的位置。 請注意,Visual Studio 僅支援原生 AOT 和 GDB for Linux 容器。
# These ARGs allow for swapping out the base used to make the final image when debugging from VS
ARG LAUNCHING_FROM_VS
# This sets the base image for final, but only if LAUNCHING_FROM_VS has been defined
ARG FINAL_BASE_IMAGE=${LAUNCHING_FROM_VS:+aotdebug}
# ... (other stages omitted)
# This stage is used as the base for the final stage when launching from VS to support debugging in regular mode (Default when not using the Debug configuration)
FROM base as aotdebug
USER root
# Install GDB to support native debugging
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
gdb
USER app
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
FROM ${FINAL_BASE_IMAGE:-mcr.microsoft.com/dotnet/runtime-deps:8.0} AS final
WORKDIR /app
EXPOSE 8080
COPY --from=publish /app/publish .
ENTRYPOINT ["./WebApplication1"]
您可以在 Dockerfile 中使用 aotstage
來自定義在除錯時所使用的映像檔,而不會影響未從 Visual Studio 啟動或在生產環境中使用的最終映像檔。 例如,您可以安裝工具,以便只在偵錯期間使用。
相關內容
- 在Visual Studio 中自定義 Docker 容器
- 從命令行建置容器專案