Search code examples
docker.net-coredockerfileprotocol-buffers

C# Protobuf project fails to build in Docker


I have a solution containing a protobuf definition file as a class library, and a gRPC service referencing the protobuf definition file. It's tied together with a solution file in the root folder.

If I build the project on my Windows machine, there's no issue:

$ dotnet build "GrpcService/GrpcService.csproj" -c Release -o build
MSBuild version 17.5.0+6f08c67f3 for .NET
  Determining projects to restore...
  Restored ...\DockerTest\GrpcService\GrpcService.csproj (in 131 ms).
  GrpcService -> ...\DockerTest\build\GrpcService.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:01.14

After building I'm able to start the gRPC service with the command dotnet .\build\GrpcService.dll.

After that I'm trying to get my solution to build inside a Docker container. I've created a Dockerfile that looks like this:

FROM mcr.microsoft.com/dotnet/sdk:7.0.203-alpine3.17 AS build

WORKDIR /src

COPY DockerTest.sln ./
COPY Test.Grpc/*.csproj ./Test.Grpc/
COPY GrpcService/*.csproj ./GrpcService/

RUN dotnet restore
COPY . .

RUN dotnet build "GrpcService/GrpcService.csproj" -c Release -o /app/publish/backend

And when I try to build the project inside a Docker container, the build fails because the proto builder can't find /src/GrpcService/GrpcService.csproj.

$ docker build .
[+] Building 47.8s (12/12) FINISHED
 => [internal] load build definition from Dockerfile                                                               0.0s
 => => transferring dockerfile: 32B                                                                                0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 35B                                                                                   0.0s
 => [internal] load metadata for mcr.microsoft.com/dotnet/sdk:7.0.203-alpine3.17                                   0.5s
 => [1/8] FROM mcr.microsoft.com/dotnet/sdk:7.0.203-alpine3.17@sha256:626f01d39214df0611f7e4a29083447dbeb80b5f42e  0.0s
 => [internal] load build context                                                                                  0.0s
 => => transferring context: 2.10kB                                                                                0.0s
 => CACHED [2/8] WORKDIR /src                                                                                      0.0s
 => [3/8] COPY DockerTest.sln ./                                                                                   0.1s
 => [4/8] COPY Test.Grpc/*.csproj ./Test.Grpc/                                                                     0.1s
 => [5/8] COPY GrpcService/*.csproj ./GrpcService/                                                                 0.1s
 => [6/8] RUN dotnet restore                                                                                      43.9s
 => [7/8] COPY . .                                                                                                 1.1s
 => ERROR [8/8] RUN dotnet build "GrpcService/GrpcService.csproj" -c Release -o /app/publish/backend               1.9s
------
 > [8/8] RUN dotnet build "GrpcService/GrpcService.csproj" -c Release -o /app/publish/backend:
#12 0.499 MSBuild version 17.5.1+f6fdcf537 for .NET
#12 0.986   Determining projects to restore...
#12 1.493   All projects are up-to-date for restore.
#12 1.814 /root/.nuget/packages/grpc.tools/2.49.0/build/_protobuf/Google.Protobuf.Tools.targets(280,5): error MSB6003: The specified task executable "/root/.nuget/packages/grpc.tools/2.49.0/tools/linux_x64/protoc" could not be run. System.ComponentModel.Win32Exception (2): An error occurred trying to start process '/root/.nuget/packages/grpc.tools/2.49.0/tools/linux_x64/protoc' with working directory '/src/GrpcService'. No such file or directory [/src/GrpcService/GrpcService.csproj]
#12 1.814 /root/.nuget/packages/grpc.tools/2.49.0/build/_protobuf/Google.Protobuf.Tools.targets(280,5): error MSB6003:    at System.Diagnostics.Process.ForkAndExecProcess(ProcessStartInfo startInfo, String resolvedFilename, String[] argv, String[] envp, String cwd, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, Int32& stdinFd, Int32& stdoutFd, Int32& stderrFd, Boolean usesTerminal, Boolean throwOnNoExec) [/src/GrpcService/GrpcService.csproj]
#12 1.814 /root/.nuget/packages/grpc.tools/2.49.0/build/_protobuf/Google.Protobuf.Tools.targets(280,5): error MSB6003:    at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo) [/src/GrpcService/GrpcService.csproj]
#12 1.814 /root/.nuget/packages/grpc.tools/2.49.0/build/_protobuf/Google.Protobuf.Tools.targets(280,5): error MSB6003:    at Microsoft.Build.Utilities.ToolTask.ExecuteTool(String pathToTool, String responseFileCommands, String commandLineCommands) [/src/GrpcService/GrpcService.csproj]
#12 1.814 /root/.nuget/packages/grpc.tools/2.49.0/build/_protobuf/Google.Protobuf.Tools.targets(280,5): error MSB6003:    at Microsoft.Build.Utilities.ToolTask.Execute() [/src/GrpcService/GrpcService.csproj]
#12 1.821
#12 1.821 Build FAILED.
#12 1.821
#12 1.821 /root/.nuget/packages/grpc.tools/2.49.0/build/_protobuf/Google.Protobuf.Tools.targets(280,5): error MSB6003: The specified task executable "/root/.nuget/packages/grpc.tools/2.49.0/tools/linux_x64/protoc" could not be run. System.ComponentModel.Win32Exception (2): An error occurred trying to start process '/root/.nuget/packages/grpc.tools/2.49.0/tools/linux_x64/protoc' with working directory '/src/GrpcService'. No such file or directory [/src/GrpcService/GrpcService.csproj]
#12 1.821 /root/.nuget/packages/grpc.tools/2.49.0/build/_protobuf/Google.Protobuf.Tools.targets(280,5): error MSB6003:    at System.Diagnostics.Process.ForkAndExecProcess(ProcessStartInfo startInfo, String resolvedFilename, String[] argv, String[] envp, String cwd, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, Int32& stdinFd, Int32& stdoutFd, Int32& stderrFd, Boolean usesTerminal, Boolean throwOnNoExec) [/src/GrpcService/GrpcService.csproj]
#12 1.821 /root/.nuget/packages/grpc.tools/2.49.0/build/_protobuf/Google.Protobuf.Tools.targets(280,5): error MSB6003:    at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo) [/src/GrpcService/GrpcService.csproj]
#12 1.821 /root/.nuget/packages/grpc.tools/2.49.0/build/_protobuf/Google.Protobuf.Tools.targets(280,5): error MSB6003:    at Microsoft.Build.Utilities.ToolTask.ExecuteTool(String pathToTool, String responseFileCommands, String commandLineCommands) [/src/GrpcService/GrpcService.csproj]
#12 1.821 /root/.nuget/packages/grpc.tools/2.49.0/build/_protobuf/Google.Protobuf.Tools.targets(280,5): error MSB6003:    at Microsoft.Build.Utilities.ToolTask.Execute() [/src/GrpcService/GrpcService.csproj]
#12 1.821     0 Warning(s)
#12 1.821     1 Error(s)
#12 1.821
#12 1.821 Time Elapsed 00:00:01.13
------
executor failed running [/bin/sh -c dotnet build "GrpcService/GrpcService.csproj" -c Release -o /app/publish/backend]: exit code: 1

But if I remove the last instruction from the Dockerfile, create a container and dump the contents from the container to see how it looks, the file is clearly there.

docker export -o dump.tar [container-id]

So what is going wrong?


Solution

  • Just ran into the same issue. For those who might encounter this in the future, the error stems from the Alpine Docker image lacking certain tools that grpc.tools needs. You can resolve this by installing the necessary tools directly into the Alpine image. Here's how:

        FROM mcr.microsoft.com/dotnet/sdk:7.0.203-alpine3.17 AS build
        RUN apk add --no-cache libc6-compat
        # ... rest of your Dockerfile ...