.NET Core 3.1 gRPC Docker:无法使 proto 路径相对

913*_*246 1 c# visual-studio docker .net-core grpc

问题描述

通过 Docker 发布默认的 .NET Core 3.1 gRPC 服务(由 Visual Studio Community 2019 16.5.4 生成)由于Could not make proto path relative : error : Protos/GreeterService.proto: No such file or directory [/src/ProjectName/ProjectName.csproj].

如何繁殖

  1. 使用 .net Core 3.1 和 Docker 支持 (Linux) 创建一个新的 gRPC 项目
  2. 打开生成的Dockerfile
  3. 从第一个的复制路径中删除目录COPY(这是默认Dockerfile中的错误):

    COPY ["ProjectName/ProjectName.csproj", "ProjectName/"] => COPY ["ProjectName.csproj", "ProjectName/"]

  4. docker build .

现在该行RUN dotnet build "ProjectName.csproj" -c Release -o /app/build抛出一个错误:

Protos : warning : directory does not exist. [/src/ProjectName/ProjectName.csproj]
Could not make proto path relative : error : Protos/GreeterService.proto: No such file or directory [/src/ProjectName/ProjectName.csproj]
Run Code Online (Sandbox Code Playgroud)

但是如果你进入容器,文件实际上就在这个位置:

root@1b49365bc690:/src/ProjectName# ls
ProjectName.csproj  obj
Run Code Online (Sandbox Code Playgroud)

我试过的

我找不到关于这个问题的太多信息,因此我找到的唯一有用的看似答案是这个 SO 答案,它建议ProtoRoot="Protos"在 .csproj 文件中添加,但遗憾的是这没有帮助。

此外,我尝试dotnet build从具有各种目标路径组合的不同工作目录手动执行命令,但没有任何效果。详细标志也没有提供任何有用的信息:

    Task "ProtoCompile"
      /root/.nuget/packages/grpc.tools/2.27.0/tools/linux_x64/protoc --csharp_out=obj/Release/netcoreapp3.1 --plugin=protoc-gen-grpc=/root/.nuget/packages/grpc.tools/2.27.0/tools/linux_x64/grpc_csharp_plugin --grpc_out=obj/Release/netcoreapp3.1 --grpc_opt=no_client --proto_path=/root/.nuget/packages/grpc.tools/2.27.0/build/native/include --proto_path=Protos --dependency_out=obj/Release/netcoreapp3.1/1255d1a520d30ea4_greet.protodep --error_format=msvs Protos/greet.proto
1:7>Protos : warning : directory does not exist. [/src/ProjectName/ProjectName.csproj]
1:7>Could not make proto path relative : error : Protos/greet.proto: No such file or directory [/src/ProjectName/ProjectName.csproj]
Run Code Online (Sandbox Code Playgroud)

我希望有人能帮我解决这个问题;先感谢您。

资源

Dockerfile:

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

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["ProjectName.csproj", "ProjectName/"]
RUN dotnet restore "ProjectName/ProjectName.csproj"
COPY . .
WORKDIR "/src/ProjectName"
RUN dotnet build "ProjectName.csproj" -c Release -o /app/build

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

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ProjectName.dll"]
Run Code Online (Sandbox Code Playgroud)

问候.proto:

syntax = "proto3";

option csharp_namespace = "ProjectName";

package greet;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply);
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}
Run Code Online (Sandbox Code Playgroud)

.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UserSecretsId>secretsId</UserSecretsId>
    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
  </PropertyGroup>

  <ItemGroup>
    <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
  </ItemGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

Gre*_*Dev 6

在此处添加评论,因为我有相同的错误消息,但原因不同。就我而言,我在 Windows 上构建 Linux docker 映像。

在我的 csproj 中,Proto 被包含为“Protos\MyService.proto”——结果在文件系统上文件名是 Myservice.proto(小写的“s”)——显然 Linux 构建容器区分大小写,因此;“无此文件或目录”!

很容易修复,但我花了大约一个小时的时间挠头