We are running into a pretty odd issue in creating a docker image for one of our APIs that contain gRPC protos in a separate project that is referenced by as Web API project.
The most notable difference here is that the proto files reside in a separate project. We have another example where the proto file resides in the the main Web API project and the Dockerfile runs just fine for that structure.
This solution has multiple projects, and all of them work well, except the one that has the gRPC. Here is the structure that matters:
We have a folder called "EventsEngine" that contains the REST API project called "HtLabs.Blox.EventsApi" which contains the Dockerfile. This project references another project "HtLabs.Events.Services" which contains a sub-folder called Inventory/Proto which contains the proto file.
HtECommerce.sln
EventsEngine
HtLabs.Blox.EventsApi
Dockerfile
HtLabs.Events.Services
Inventory
Protos
SimpleInventory.proto
The csproj for the HtLabs.Events.Services shows the protos correctly setup like so:
<ItemGroup>
<Protobuf Include="Inventory\Protos\SimpleInventory.proto" GrpcServices="Server,Client" />
<Protobuf Include="Events\Protos\Events.proto" GrpcServices="Server" />
<Protobuf Include="Events\Protos\Tenants.proto" GrpcServices="Server" />
</ItemGroup>
The Dockerfile is very complex, as there are multiple projects involved, but the main stuff is as follows:
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 ["*.sln", "./"]
COPY ["EventsEngine/HtLabs.Blox.EventsApi/HtLabs.Blox.EventsApi.csproj", "HtLabs.Blox.EventsApi/"]
COPY ["EventsEngine/HtLabs.Events.Services/HtLabs.Events.Services.csproj", "HtLabs.Events.Services/"]
COPY ["EventsEngine/HtLabs.Blox.EventsApi/nuget.config", ""]
RUN dotnet restore "HtLabs.Blox.EventsApi/HtLabs.Blox.EventsApi.csproj"
COPY . .
WORKDIR "/src/HtLabs.Blox.EventsApi"
RUN dotnet build "HtLabs.Blox.EventsApi.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "HtLabs.Blox.EventsApi.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "HtLabs.Blox.EventsApi.dll"]
We also understand that Dockerfiles need to be run from the root (i.e. the folder where the solution resides). This has worked very well for other microservices that do not have gRPC.
However, the moment we add a gRPC proto, we run into the following error:
Could not make proto path relative : error : Inventory/Protos/SimpleInventory.proto: No such file or directory [/src/HtLabs.Events.Services/HtLabs.Events.Services.csproj]
A few questions:
- Do we need to restore each referenced project? As in, do I need to include each project in the Dockerfile?
RUN dotnet restore "HtLabs.Events.Services/HtLabs.Events.Services.csproj"
I have read elsewhere that this might have to do something with the way the Dockerfile is created. The marked answer shows a Dockerfile but doesn't really state exactly what was changed on the Dockerfile to make this work. Any thoughts?
I have also read something about setting ProtoRoot but couldn't find any concrete/correct examples of doing so.
Would really appreciate any assistance here. Thank you!