Search code examples
docker.net-coreonnxruntime

Adding onnxruntime Library to a .Net Core Docker Container for Linux


I am trying to deploy a game server on a .NET 5.0 Docker container for Linux deployment. My current Dockerfile looks like this, and it has been working fine so far. My code is packaged into a dll that is in the Darkrift_Server_Local/Plugins folder. Darkrift.Server.Console.dll is a third-party networking wrapper that loads the plugin and runs my logic:

FROM mcr.microsoft.com/dotnet/runtime:5.0
COPY DarkRift_Server_Local/ App/
EXPOSE 4296/udp
EXPOSE 4296/tcp
WORKDIR /App
ENTRYPOINT ["dotnet", "./Lib/DarkRift.Server.Console.dll"]

Now I want to add a pre-trained ONNX model to my server for AI opponents to use. I have added the Microsoft.ML.OnnxRuntime Nuget package to my project, and my code works when I run it on my Windows 10 (using a powershell to execute Darkrift.Server.Console.dll).

However, I am not able to make this work in the Docker container, because it is unable to locate the onnxruntime.dll file. The specific error is below:

System.TypeInitializationException: The type initializer for 'Microsoft.ML.OnnxRuntime.NativeMethods' threw an exception.

---> System.DllNotFoundException: Unable to load shared library 'onnxruntime' or one of its dependencies.

I've tried copying the onnxruntime.dll file, generated during the build, to various locations in the Darkrift_Server_Local folder, but it has not been working. I'm rather new to Docker and have gotten back to .NET after several years, so having a little trouble figuring out how this is supposed to work. Would appreciate any direction on this.

EDIT: In response to the comment. I'm building the project using VS2019 with Release/Any CPU. The package inclusion code is as follows:

  <ItemGroup>
    <PackageReference Include="com.playfab.csharpgsdk" Version="0.10.200325" />
    <PackageReference Include="Microsoft.ML.OnnxRuntime" Version="1.7.0" />
  </ItemGroup>

I have also tried using dotnet publish -c Release and copying over the runtimes folder that is created in the publish folder to various locations in my Darkrift_Server_Local folder - should have mentioned that.


Solution

  • Since you are compiling on Windows, but using Linux container, you have to make sure that you are publishing for the correct runtime.

    First, publish with dotnet publish -r linux-x64. You may want to specific -o <path> to make it easier to find.

    You can then copy those inside your image with your Dockerfile.

    Alternatively, you could build/publish in your Dockerfile itself to avoid platform issues like this.