Reputation: 377
Problem description
Publishing a default .NET Core 3.1 gRPC service (generated by Visual Studio Community 2019 16.5.4) via Docker fails due to Could not make proto path relative : error : Protos/GreeterService.proto: No such file or directory [/src/ProjectName/ProjectName.csproj]
.
How to reproduce
Remove the directory from the copy path of the first COPY
(this is an error in the default Dockerfile):
COPY ["ProjectName/ProjectName.csproj", "ProjectName/"]
=> COPY ["ProjectName.csproj", "ProjectName/"]
Run docker build .
Now the line RUN dotnet build "ProjectName.csproj" -c Release -o /app/build
throws an error:
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]
But if you go into the container, the file actually exists at exactly this location:
root@1b49365bc690:/src/ProjectName# ls
ProjectName.csproj obj
What I tried
I couldn't find much regarding this issue, therefore the only helpful seeming answer I found was this SO answer which recommends to add ProtoRoot="Protos"
within the .csproj file, but sadly this didn't help.
Furthermore I tried to manually execute the dotnet build
command from different working directories with various target path combinations but none worked. The verbose flag also didn't provide any useful information:
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]
I hope someone can help me out with this problem; thank you in advance.
Ressources
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"]
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>
Upvotes: 2
Views: 6400
Reputation: 623
Adding a comment here as I had the same Error message but for a different reason. In my case, I was on Windows building a Linux docker image.
In my csproj, the Proto was included as "Protos\MyService.proto" - turns out on the filesystem the filename was Myservice.proto (lowercase 's') - obviously the Linux build container is case sensitive, hence; "No such file or directory"!
Easy fix but took me about an hour of head scratching 😁
Upvotes: 11
Reputation: 377
I got it to work by changing the Dockerfile to following:
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"]
I'm not 100% sure why this works, but I guess that it has something to do with how the gRPC compiler discovers which files it has to compile.
Upvotes: -1