dotnet7下docker镜像构建之XML打包丢失问题

发布时间 2023-08-17 16:22:21作者: LandWind

注意

暂时值适用 .NET SDK 7.0.100以上
其他版本,可以参考举例中的配置host项目

省流原因

dotnet publish 发布命令对于引用项目的xml不会拷贝到发布目录

举例

host项目依赖api项目,api项目依赖utils包,utils包中的xml文件在host项目swagger需要使用
xml文件

一般包引用xml文件输出配置,以下项目配置将包中二级目录**.xml拷贝到输出目录(构建/发布)

<ItemGroup>
	<PackageReference Include="xxx.yyy" Version="1.0.0">
		<CopyToOutputDirectory>*\*.xml</CopyToOutputDirectory>
	</PackageReference>
</ItemGroup>

<Target Name="AfterTargetsBuild" AfterTargets="Build">
	<ItemGroup>
		<PackageReferenceFiles
			   Condition="%(PackageReference.CopyToOutputDirectory) != ''"
			   Include="$(NugetPackageRoot)\%(PackageReference.Identity)\%(PackageReference.Version)\%(PackageReference.CopyToOutputDirectory)" />
	</ItemGroup>
	<Message Text="Build Copying XML docs to $(OutputPath)" Importance="High" />
	<Copy SourceFiles="@(PackageReferenceFiles)" DestinationFolder="$(OutDir)" />
</Target>

<Target Name="AfterTargetsPublish" AfterTargets="Publish">
	<ItemGroup>
		<PackageReferenceFiles
			   Condition="%(PackageReference.CopyToOutputDirectory) != ''"
			   Include="$(NugetPackageRoot)\%(PackageReference.Identity)\%(PackageReference.Version)\%(PackageReference.CopyToOutputDirectory)" />
	</ItemGroup>
	<Message Text="Publish Copying XML docs to $(PublishDir)" Importance="High" />
	<Copy SourceFiles="@(PackageReferenceFiles)" DestinationFolder="$(PublishDir)" />
</Target>

解决方案

第一步:

项目配置中添加一下配置项
CopyDocumentationFilesFromPackages
将此属性设置为 true 时,将项目中 PackageReference 项的所有生成的 XML 文档文件复制到生成输出。 请注意,启用此功能将导致部署捆绑包大小增加。

此属性是在 .NET SDK 7.0.100 中引入的,尽管它默认为未指定。

<PropertyGroup>
	<CopyDocumentationFilesFromPackages>true</CopyDocumentationFilesFromPackages>
</PropertyGroup> 

第二步:

Dockerfile 文件配置关键
添加环境变量 NUGET_XMLDOC_MODE none 支持xml作为普通文件输出

微软推荐的镜像构建流程如下
此 Dockerfile 使用多阶段生成,通过分层生成并仅保留所需的项目来优化映像的最终大小。 有关详细信息,请参阅 Docker 文档:多阶段生成。

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env
WORKDIR /App

# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:7.0
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]

以上构建镜像后会缺失xml文件
修改后

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env
WORKDIR /App

// 注意
ENV NUGET_XMLDOC_MODE none

# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:7.0

// 注意
ENV NUGET_XMLDOC_MODE none

WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]

参考文章