You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core Docker镜像构建时部分文件夹未复制的问题

ASP.NET Core Docker镜像构建中部分文件夹未复制问题排查

问题背景

构建ASP.NET Core Web应用Docker镜像时,出现MyNotes文件夹未被复制到最终镜像的异常,仅MyData文件夹存在。相关Dockerfile及目标目录结构如下:

Dockerfile内容

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["Nuget.config", "."]
COPY ["MyProject/MyProject.csproj", "MyProject/"]
RUN dotnet restore "MyProject/MyProject.csproj" --configfile /src/Nuget.config
COPY . .

WORKDIR /src/MyProject
RUN dotnet build "MyProject.csproj" -c Release -o /app/build --configfile /src/Nuget.config

RUN mkdir -p /app/publish/MyNotes
RUN mkdir -p /app/publish/MyData
RUN cp -R "../packages/mylibrary/2.0.3/lib/netstandard2.0/MyNotes" "/app/publish/"
RUN cp -R "../packages/mylibrary/2.0.3/lib/netstandard2.0/MyData" "/app/publish/"

#COPY ["../packages/mylibrary/2.0.3/lib/netstandard2.0/MyNotes", "/app/publish/MyNotes"]
#COPY ["../packages/mylibrary/2.0.3/lib/netstandard2.0/MyNotes/ps/", "/app/publish/MyNotes/ps/"]
#COPY ["../packages/mylibrary/2.0.3/lib/netstandard2.0/MyNotes/pc/", "/app/publish/MyNotes/pc/"]
#COPY ["../packages/mylibrary/2.0.3/lib/netstandard2.0/MyData", "/app/publish/MyData"]

FROM build AS publish
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish --no-restore

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
RUN find . -type f
ENTRYPOINT ["dotnet", "MyProject.dll"]

目标目录结构

MyNotes
  |_ pc
      |_ example1.txt
      |_ example2.txt
  |_ ps
      |_ example4.txt

MyData
  |_ example7.txt

异常现象

  • 构建阶段执行RUN find . -type f显示两个文件夹已复制
  • 镜像运行后进入容器执行ls,仅MyData存在,MyNotes文件夹缺失
  • 使用注释中的COPY命令也出现相同问题

问题根源

publish阶段的dotnet publish命令会完全覆盖/app/publish目录。

你在build阶段手动将MyNotes和MyData复制到了/app/publish,但后续执行dotnet publish时,该命令会将编译后的项目输出写入/app/publish,直接覆盖之前手动复制的内容。MyData之所以保留,大概率是因为你的项目本身包含MyData目录,dotnet publish会自动将其复制到发布目录,而MyNotes不在项目范围内,所以被覆盖后消失。

修复方案

方案一:调整复制顺序,在publish完成后执行复制

将手动复制文件夹的操作移到publish阶段之后,避免被dotnet publish覆盖:

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["Nuget.config", "."]
COPY ["MyProject/MyProject.csproj", "MyProject/"]
RUN dotnet restore "MyProject/MyProject.csproj" --configfile /src/Nuget.config
COPY . .

WORKDIR /src/MyProject
RUN dotnet build "MyProject.csproj" -c Release -o /app/build --configfile /src/Nuget.config

FROM build AS publish
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish --no-restore
# 将复制操作移到publish命令之后
RUN cp -R "../packages/mylibrary/2.0.3/lib/netstandard2.0/MyNotes" "/app/publish/"
RUN cp -R "../packages/mylibrary/2.0.3/lib/netstandard2.0/MyData" "/app/publish/"

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
RUN find . -type f
ENTRYPOINT ["dotnet", "MyProject.dll"]

方案二:通过项目配置自动复制依赖文件(推荐)

修改项目文件MyProject.csproj,让dotnet publish自动将依赖文件复制到发布目录,无需手动操作:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <!-- 保留原有配置 -->
  <ItemGroup>
    <!-- 添加以下配置,指定要复制的文件 -->
    <Content Include="..\packages\mylibrary\2.0.3\lib\netstandard2.0\MyNotes\**">
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
      <Link>MyNotes\%(RecursiveDir)%(Filename)%(Extension)</Link>
    </Content>
    <Content Include="..\packages\mylibrary\2.0.3\lib\netstandard2.0\MyData\**">
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
      <Link>MyData\%(RecursiveDir)%(Filename)%(Extension)</Link>
    </Content>
  </ItemGroup>
</Project>

修改后,删除Dockerfile中所有手动复制MyNotes和MyData的命令,dotnet publish会自动完成文件复制。

内容的提问来源于stack exchange,提问作者Snake Eyes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:42:03