我需要把ASP打包.NET Core 6.0 Web API使用Docker.这个项目可以在我的这GitHub Repo个房间里找到.

该项目的 struct 如下:

───PlaygroundApiDockerized
    │
    ├───src
    │   ├───Playground.API
    |   |   ├───Dockerfile
    |   |   └───Playground.API.csproj
    |   |   
    │   └───Playground.Core
    |       └───Playground.Core.csproj
    │   
    ├───test
    │   ├───Playground.Tests
    │       └───Playground.Tests.csproj
    │
    ├───Playground.sln
    └───docker-compose.yml

该API项目依赖于一个名为Playground.Core的简单C#类库,并有一个Dockerfile.

Dockerfile的内容:

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

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["src/Playground.API/Playground.API.csproj", "Playground.API/"]
COPY ["src/Playground.Core/Playground.Core.csproj", "Playground.Core/"]
RUN dotnet restore "src/Playground.API/Playground.API.csproj"
COPY . .
WORKDIR "/src/Playground.API"
RUN dotnet build "Playground.API.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Playground.API.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Playground.API.dll"]

docker-compose文件如下所示:

version: '3.7'

services:
  playground-api:
    build:
      context: ./
      dockerfile: src/Playground.API/Dockerfile
    restart: always
    ports:
      - "7987:80"

My expectation is,when the 100 command is exectuted in the solution root directory, the API is started.

But the command results in the following error below.

I understand that the current working directory where the command is executed is the context directory specified in the 100. In my example, the context is the solution root. I simply can't figure out how to specify the paths in the 101. Does anyone know?

Creating network "playgroundapidockerized_default" with the default driver
Building playground-api
[+] Building 2.2s (11/18)
 => [internal] load build definition from Dockerfile                                                               0.0s
 => => transferring dockerfile: 720B                                                                               0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for mcr.microsoft.com/dotnet/sdk:6.0                                                  0.8s
 => [internal] load metadata for mcr.microsoft.com/dotnet/aspnet:6.0                                               0.0s
 => [internal] load build context                                                                                  0.3s
 => => transferring context: 13.35MB                                                                               0.2s
 => [base 1/2] FROM mcr.microsoft.com/dotnet/aspnet:6.0                                                            0.0s
 => [build 1/8] FROM mcr.microsoft.com/dotnet/sdk:6.0@sha256:fde93347d1cc74a03f1804f113ce85add00c6f0af15881181165  0.0s
 => CACHED [build 2/8] WORKDIR /src                                                                                0.0s
 => [build 3/8] COPY [src/Playground.API/Playground.API.csproj, Playground.API/]                                   0.1s
 => [build 4/8] COPY [src/Playground.Core/Playground.Core.csproj, Playground.Core/]                                0.0s
 => ERROR [build 5/8] RUN dotnet restore "src/Playground.API/Playground.API.csproj"                                0.9s
------
 > [build 5/8] RUN dotnet restore "src/Playground.API/Playground.API.csproj":
#13 0.814 MSBUILD : error MSB1009: Project file does not exist.
#13 0.814 Switch: src/Playground.API/Playground.API.csproj
------
executor failed running [/bin/sh -c dotnet restore "src/Playground.API/Playground.API.csproj"]: exit code: 1
ERROR: Service 'playground-api' failed to build : Build failed

推荐答案

复制项目文件时,图像中的当前目录为/src,并将其复制到Playground.API/,因此项目文件的绝对路径为/src/Playground.API/Playground.API.csproj.

然后运行dotnet restore时,使用相对路径src/Playground.API/Playground.API.csproj.所以它寻找/src/src/Playground.API/Playground.API.csproj个不存在的.

稍后,当你用COPY . .复制所有文件时,你会从主机获得目录 struct ,所以现在你的文件变成/src/src/Playground.API/Playground.API.csproj等.此时,你有两个项目文件的副本./src/Playground.API分之一和/src/src/Playground.API分之一.

我认为最好的办法是将主机目录 struct 保持在工作目录下,即/src/src/....为了避免混淆,我将工作目录重命名为/src以外的名称.像这样的

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

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /app
COPY ["src/Playground.API/Playground.API.csproj", "src/Playground.API/"]
COPY ["src/Playground.Core/Playground.Core.csproj", "src/Playground.Core/"]
RUN dotnet restore "src/Playground.API/Playground.API.csproj"
COPY . .
WORKDIR "/app/src/Playground.API"
RUN dotnet build "Playground.API.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Playground.API.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Playground.API.dll"]

Csharp相关问答推荐

如何将ref T*重新解释为ref nint?

如何使嵌套for-loop更高效?

使用yaml将Azure函数代码部署到FunctionApp插槽时出现问题(zip未找到)

使用命令初始化可绑定属性

将XPS转换为PDF C#

为什么任务需要在内部使用ManualResetEventSlim?

使用Audit.EntityFramework,我如何将外键的值设置为相关实体上的属性?

使页面内容居中

创建临时Collection 最有效的方法是什么?堆栈分配和集合表达式之间的区别?

如何在C#中从正则表达式中匹配一些数字但排除一些常量(也是数字)

为什么在使用动态obj+类obj时会调用串联?

C#中浮点数的System.Text.Json序列化问题

按需无缝转码单个HLS数据段

在C#中有没有办法减少大型数组中新字符串的分配?

C#中类库项目的源代码生成器

在等待OnGetAsync时打开Razor Page显示微调器

将字符串类型日期输入(yyyy-mm-ddthh:mm:ss)转换为MM/dd/yyyy格式

为什么在使用JsonDerivedType序列化泛型时缺少$type?

在C#中通过Matheval使用自定义公式

Windows 10上埃及标准时间的时区偏移不正确