无法从Dockerfile构建.NET Core 5项目镜像的问题排查
Docker构建.NET Core 5镜像失败:找不到项目文件的原因及解决办法
问题场景
我有一个包含4个项目的.NET Core 5解决方案,Web项目引用了其他所有项目。使用Visual Studio生成Dockerfile后,在Dockerfile所在目录执行命令docker build -t pnvimage .时,报错:
failed to compute cache key "/PhoneNumberValidator.Application/PhoneNumberValidator.Application.csproj" not found: not found
但该csproj文件实际存在于对应项目目录中。
项目结构如下:
PhoneNumberValidator/ ├── PhoneNumberValidator.Web/ │ ├── Dockerfile │ ├── PhoneNumberValidator.Web.csproj │ └── ... ├── PhoneNumberValidator.Entities/ │ ├── PhoneNumberValidator.Entities.csproj │ └── ... ├── PhoneNumberValidator.DAL/ │ ├── PhoneNumberValidator.DAL.csproj │ └── ... ├── PhoneNumberValidator.Application/ │ ├── PhoneNumberValidator.Application.csproj │ └── ... └── ...
Visual Studio生成的Dockerfile内容:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. #Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed. #For more information, please see https://aka.ms/containercompat FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build WORKDIR /src COPY ["PhoneNumberValidator.Web/PhoneNumberValidator.Web.csproj", "PhoneNumberValidator.Web/"] COPY ["PhoneNumberValidator.Entities/PhoneNumberValidator.Entities.csproj", "PhoneNumberValidator.Entities/"] COPY ["PhoneNumberValidator.DAL/PhoneNumberValidator.DAL.csproj", "PhoneNumberValidator.DAL/"] COPY ["PhoneNumberValidator.Application/PhoneNumberValidator.Application.csproj", "PhoneNumberValidator.Application/"] RUN dotnet restore "PhoneNumberValidator.Web/PhoneNumberValidator.Web.csproj" COPY . . WORKDIR "/src/PhoneNumberValidator.Web" RUN dotnet build "PhoneNumberValidator.Web.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "PhoneNumberValidator.Web.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "PhoneNumberValidator.Web.dll"]
失败原因
核心问题是构建上下文路径错误:
- Dockerfile位于
PhoneNumberValidator.Web/目录下,执行docker build时如果以该目录为上下文(.代表当前目录),Docker只能访问PhoneNumberValidator.Web/内部的文件,无法访问同级的PhoneNumberValidator.Application/等其他项目目录。 - Dockerfile里的
COPY指令基于构建上下文路径查找文件,尝试找PhoneNumberValidator.Application/PhoneNumberValidator.Application.csproj时,会在当前上下文(PhoneNumberValidator.Web/)下查找,自然找不到目标文件。
解决办法
方案1:调整构建命令的上下文路径(推荐)
切换到解决方案根目录(PhoneNumberValidator/)执行构建命令,同时指定Dockerfile的路径:
docker build -t pnvimage -f PhoneNumberValidator.Web/Dockerfile .
此时构建上下文为整个解决方案根目录,Docker可以找到所有项目的csproj文件,完全匹配Dockerfile里的路径预期。
方案2:修改Dockerfile中的路径(不推荐)
如果必须在PhoneNumberValidator.Web/目录下执行构建,需要调整Dockerfile里所有跨项目的COPY路径,添加上级目录前缀../:
# 修改前 COPY ["PhoneNumberValidator.Entities/PhoneNumberValidator.Entities.csproj", "PhoneNumberValidator.Entities/"] # 修改后 COPY ["../PhoneNumberValidator.Entities/PhoneNumberValidator.Entities.csproj", "PhoneNumberValidator.Entities/"]
同理,PhoneNumberValidator.DAL和PhoneNumberValidator.Application的COPY指令都需要做相同修改。但这种方式会和Visual Studio自动生成的Dockerfile结构冲突,后期维护成本高,不推荐使用。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

