使用docker compose up --build构建.NET多项目时路径错误求助
Docker Compose构建.NET多项目解决方案失败问题
我有一个包含API、CLIENT、IdentityServer及SQL服务的.NET多项目解决方案,已编写对应的三个Dockerfile和docker-compose.yaml。单独执行docker build -f ./ShopProject.Api/Dockerfile -t vazaras/shopproject-api .能成功构建镜像并正常运行,但执行docker compose up --build时,构建过程中出现无法找到API及Shared等项目路径的错误。
API项目Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR /src COPY ["ShopProject.Api/ShopProject.Api.csproj", "ShopProject.Api/"] COPY ["ShopProject.Shared/ShopProject.Shared.csproj", "ShopProject.Shared/"] COPY ["ShopProject.Application/ShopProject.Application.csproj", "ShopProject.Application/"] COPY ["ShopProject.Infrastructure/ShopProject.Infrastructure.csproj","ShopProject.Infrastructure/"] COPY ["ShopProject.Domain/ShopProject.Domain.csproj", "ShopProject.Domain/"] COPY ["ShopProject.Persistence/ShopProject.Persistence.csproj", "ShopProject.Persistence/"] RUN dotnet restore "ShopProject.Api/ShopProject.Api.csproj" COPY . . WORKDIR "/src/ShopProject.Api" RUN dotnet build "ShopProject.Api.csproj" -c Release -o /app/build RUN dotnet publish "ShopProject.Api.csproj" -c Release -o /app/publish /p:UseAppHost=false FROM mcr.microsoft.com/dotnet/aspnet:7.0 EXPOSE 80 EXPOSE 443 WORKDIR /app COPY --from=build /app/publish . ENTRYPOINT ["dotnet", "ShopProject.Api.dll"]
CLIENT项目Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR /app COPY ["ShopProject.Client/ShopProject.Client.csproj", "ShopProject.Client/"] COPY ["ShopProject.Shared/ShopProject.Shared.csproj", "ShopProject.Shared/"] RUN dotnet restore "ShopProject.Client/ShopProject.Client.csproj" COPY . . RUN dotnet publish "ShopProject.Client/ShopProject.Client.csproj" -c Release -o /app/publish /p:UseAppHost=false FROM nginx:alpine EXPOSE 80 EXPOSE 443 COPY --from=build /app/publish/wwwroot /usr/share/nginx/html
IdentityServer项目Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR /src COPY ["DuendeIdentityServer/DuendeIdentityServer.csproj", "DuendeIdentityServer/"] RUN dotnet restore "DuendeIdentityServer/DuendeIdentityServer.csproj" COPY . . WORKDIR "/src/DuendeIdentityServer" RUN dotnet build "DuendeIdentityServer.csproj" -c Release -o /app/build RUN dotnet publish "DuendeIdentityServer.csproj" -c Release -o /app/publish /p:UseAppHost=false FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base EXPOSE 80 EXPOSE 443 WORKDIR /app COPY --from=build /app/publish . ENTRYPOINT ["dotnet", "DuendeIdentityServer.dll"]
docker-compose.yaml内容
version: '3.8' services: sqlserver: image: mcr.microsoft.com/azure-sql-edge container_name: sqlserver-shopproject environment: - ACCEPT_EULA=1 - MSSQL_SA_PASSWORD=Pass1234$ ports: - 4000:1433 identity-server: build: context: ./DuendeIdentityServer dockerfile: Dockerfile image: vazaras/shopproject-identity-server container_name: shopproject-identity-server ports: - 9000:80 - 9001:443 api: build: context: ./ShopProject.Api dockerfile: Dockerfile image: vazaras/shopproject-api container_name: shopproject-api ports: - 9002:80 - 9003:443 frontend: build: context: ./ShopProject.Client dockerfile: Dockerfile image: vazaras/shopproject-frontend container_name: shopproject-frontend ports: - 9004:80 - 9005:443
文件目录结构
. ├── DuendeIdentityServer │ ├── Config.cs │ ├── Data │ ├── Dockerfile │ ├── DuendeIdentityServer.csproj │ ├── HostingExtensions.cs │ ├── Migrations │ ├── Models │ ├── Pages │ ├── Program.cs │ ├── Properties │ ├── SeedData.cs │ ├── Services │ ├── appsettings.json │ ├── bin │ ├── buildschema.bat │ ├── keys │ ├── obj │ └── wwwroot ├── ShopProject.Api │ ├── Controllers │ ├── Dockerfile │ ├── Program.cs │ ├── Properties │ ├── Services │ ├── ShopProject.Api.csproj │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── bin │ ├── logs │ └── obj ├── ShopProject.Application │ ├── Common │ ├── DependencyInjection.cs │ ├── ShopProject.Application.csproj │ ├── bin │ └── obj ├── ShopProject.Client │ ├── App.razor │ ├── Dockerfile │ ├── Pages │ ├── Program.cs │ ├── Properties │ ├── Shared │ ├── ShopProject.Client.csproj │ ├── _Imports.razor │ ├── bin │ ├── obj │ └── wwwroot ├── ShopProject.Domain │ ├── Common │ ├── ShopProject.Domain.csproj │ ├── bin │ └── obj ├── ShopProject.Infrastructure │ ├── DependencyInjection.cs │ ├── Services │ ├── ShopProject.Infrastructure.csproj │ ├── bin │ └── obj ├── ShopProject.Persistence │ ├── AppDbContext.cs │ ├── ConnectionStringDbContext.cs │ ├── DbContextFactory.cs │ ├── DependencyInjection.cs │ ├── DesignTimeDbContextFactoryBase.cs │ ├── ShopProject.Persistence.csproj │ ├── bin │ └── obj ├── ShopProject.Shared │ ├── ShopProject.Shared.csproj │ ├── WeatherForecast.cs │ ├── bin │ └── obj ├── ShopProject.sln ├── backup-whateverfolder-2023-10-14.txt └── docker-compose.yaml
构建情况说明
- 单独执行
docker build构建成功:构建过程无错误,最终输出“Successfully built”和“Successfully tagged”完成信息。 - 执行
docker compose up --build构建失败:构建API服务时,出现类似“找不到文件 ShopProject.Api/ShopProject.Api.csproj”的错误,无法定位依赖的项目文件。
解决方法
问题根源在于Docker Compose的构建上下文(context)设置错误:
单独构建时,你用根目录(.)作为上下文,Docker能访问所有项目文件;但docker-compose里每个服务的context设成了项目子目录,导致构建时只能看到该子目录下的文件,找不到其他依赖项目(比如ShopProject.Shared、ShopProject.Application等)。
只需修改docker-compose.yaml,将每个服务的build.context改为根目录,并指定Dockerfile的完整路径即可:
version: '3.8' services: sqlserver: image: mcr.microsoft.com/azure-sql-edge container_name: sqlserver-shopproject environment: - ACCEPT_EULA=1 - MSSQL_SA_PASSWORD=Pass1234$ ports: - 4000:1433 identity-server: build: context: . dockerfile: ./DuendeIdentityServer/Dockerfile image: vazaras/shopproject-identity-server container_name: shopproject-identity-server ports: - 9000:80 - 9001:443 api: build: context: . dockerfile: ./ShopProject.Api/Dockerfile image: vazaras/shopproject-api container_name: shopproject-api ports: - 9002:80 - 9003:443 frontend: build: context: . dockerfile: ./ShopProject.Client/Dockerfile image: vazaras/shopproject-frontend container_name: shopproject-frontend ports: - 9004:80 - 9005:443
修改后,Docker Compose构建时会以根目录为上下文,和单独执行docker build的环境一致,Dockerfile中的COPY指令就能正确找到所有依赖项目的文件,构建即可成功。
内容的提问来源于stack exchange,提问作者Adamski
相关产品推荐
相关产品推荐

