【问题标题】:.NET Core 3.1 gRPC Docker: Could not make proto path relative.NET Core 3.1 gRPC Docker:无法使原型路径相对
【发布时间】:2020-08-31 07:39:40
【问题描述】:

问题描述

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

如何重现

  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]

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

root@1b49365bc690:/src/ProjectName# ls
ProjectName.csproj  obj

我尝试了什么

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

此外,我尝试从具有各种目标路径组合的不同工作目录手动执行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]

我希望有人能帮我解决这个问题;提前谢谢你。

资源

Docker 文件:

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"]

greet.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;
}

.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>

【问题讨论】:

  • 我遇到了同样的错误,但事实证明我过于积极地调整我的 .dockerignore 文件并且我无意中添加了 protos 文件夹路径...

标签: c# visual-studio docker .net-core grpc


【解决方案1】:

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

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

很容易解决,但我花了大约一个小时挠头?

【讨论】:

    【解决方案2】:

    我通过将 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" .
    RUN dotnet restore "ProjectName.csproj"
    COPY . .
    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"]
    

    我不能 100% 确定为什么会这样,但我猜这与 gRPC 编译器如何发现它必须编译的文件有关。

    【讨论】:

      猜你喜欢
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      • 1970-01-01
      • 2020-05-22
      相关资源
      最近更新 更多