dotnet / core

.NET news, announcements, release notes, and more!
https://dot.net
MIT License
20.87k stars 4.89k forks source link

Native dll load fails in Docker container, but not when running locally #4262

Closed bhardwajs closed 4 years ago

bhardwajs commented 4 years ago

Native dll load fails in Docker container, but not when running locally

I have a .Net Standard dll which P/Invokes in a native dll compiled for win-x64. My .Net Core app runs without any issues on local machine. When I publish to a docker container containing .Net Core image, it fails to load the native dll. Are there any other dependencies?

.Net Core 3.1 on x64 Windows Docker image - mcr.microsoft.com/dotnet/core/runtime:3.1

dkmiller commented 4 years ago

I can repro this. I build the binary using dotnet build --configuration Release. Then from the /bin/Release/netcoreapp3.1 directory, run

docker run -v "$($PWD):C:\src" mcr.microsoft.com/dotnet/core/runtime:3.1 dotnet /src/VASandbox.dll

This results in the following stack trace:

Unhandled exception. Microsoft.VariantAssignment.VariantAssignmentException: Failed to initialize the library! ---> System.DllNotFoundException: Unable to load DLL 'Microsoft.VariantAssignment.Native.dll' or one of its dependencies: The specified module could not be found. (0x8007007E) at Microsoft.VariantAssignment.VariantAssignmentNativeMethods.InitializeVariantAssignments(IntPtr pAzureStorageSettings, Int32 inputLength, IntPtr logMessageDelegate, VariantAssignmentLoggerHandler& logger, VariantAssignmentHandler& handler) at Microsoft.VariantAssignment.VariantAssignmentProvider.Initialize(AzureStorageSettings azureStorageSettings) --- End of inner exception stack trace --- at Microsoft.VariantAssignment.VariantAssignmentProvider.Initialize(AzureStorageSettings azureStorageSettings) at Microsoft.VariantAssignment.VariantAssignmentProvider..ctor(AzureStorageSettings azureStorageSettings, IBufferManager bufferManager, ILogger logger) at AnE.ExP.VariantAssignment.Sandbox.Program.Main() in C:\src\variant-assignment-sandbox\VASandbox\Program.cs:line 21

leecow commented 4 years ago

@MichaelSimons and @mthalman - have a look?

MichaelSimons commented 4 years ago

Can you verify what machine you are running on? Could you please include the output of docker info?

bhardwajs commented 4 years ago

@MichaelSimons : I am running this on a Windows 10 machine with Dokcer for Windows (v 2.2.0.3). See below for Dockerfile and docker info. Please let me know if I can provide anything else for investigating the issue.

> cat Dockerfile

FROM mcr.microsoft.com/dotnet/core/runtime:3.1
COPY vasandbox/bin/Release/netcoreapp3.1/win-x64/publish/ vasandbox/
ENTRYPOINT ["dotnet", "vasandbox/vasandbox.dll"]
> docker info

 Debug Mode: false

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 4
 Server Version: 19.03.5
 Storage Driver: windowsfilter
  Windows:
 Logging Driver: json-file
 Plugins:
  Volume: local
  Network: ics internal l2bridge l2tunnel nat null overlay private transparent
  Log: awslogs etwlogs fluentd gcplogs gelf json-file local logentries splunk syslog
 Swarm: inactive
 Default Isolation: hyperv
 Kernel Version: 10.0 19577 (19577.1000.amd64fre.rs_prerelease.200228-1439)
 Operating System: Windows 10 Enterprise Version 2004 (OS Build 19577.1000)
 OSType: windows
 Architecture: x86_64
 CPUs: 8
 Total Memory: 15.84GiB
 Name: SUMITB
 ID: 4RGX:N23F:ZW5V:6PD5:3QBZ:7UW4:65EX:ZHU5:UYHB:TZQI:3Z32:UF3C
 Docker Root Dir: C:\ProgramData\Docker
 Debug Mode: true
  File Descriptors: -1
  Goroutines: 28
  System Time: 2020-03-11T14:58:10.145249-07:00
  EventsListeners: 1
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
 Product License: Community Engine
MichaelSimons commented 4 years ago

@bhardwajs - This may be a limitation with Nano Server. To validate this you could try switching to one of the .NET Framework SDK images which also contain the .NET Core SDK and runtime.

FROM mcr.microsoft.com/dotnet/framework/sdk:4.8

svick commented 4 years ago

Is it possible that your Docker is configured to run (virtualized) Linux containers, which is the default? I believe that the dotnet/core images are multi-platform, so they work for both Linux and Windows containers.

That would explain why a native Windows dll wouldn't work in the container.

MichaelSimons commented 4 years ago

@svick - That was my first thought as well which is why I asked for the docker info. The Docker Info indicates Windows Container Mode is being used.

bhardwajs commented 4 years ago

@MichaelSimons : I tried using .Net Framework SDK and that loads the native dll.

Can you think of a reason why Nano server might not support P/Invoke to native dll? For the customers of my library, I want to have as wide a range of choices for containers as possible :)

MichaelSimons commented 4 years ago

@bhardwajs - Is Microsoft.VariantAssignment.Native.dll an assembly you are coping in? I don't see this as a general P/Invoke issue on Nano Server rather something specific to your scenario. Have you verified all of your assemblies native dependencies are present within the Nano Server image? Nano Server is a very slimmed down server os variant. You may have to bring those other native dependencies yourself.

bhardwajs commented 4 years ago

@MichaelSimons Turns out our native libraries require Visual C++ runtime libraries from VC++ redistributable package (https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads).

Once I had these libraries on nano server container, I was able to get the P/Invoke assembly working.

Thanks for the help! Closing the issue.

criticalbh commented 3 years ago

@bhardwajs can you show full dockerfile please?

paulosergiosantos commented 2 years ago

When run in a docker image, instead of a .dll, shoundn't a vasandbox.so be used?

MahmoudHassan77 commented 2 years ago

@bhardwajs can you show full dockerfile please?

Do you have the docker file??

kimlehtinen commented 6 months ago

Add this to Dockerfile

RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \
    Invoke-WebRequest "https://aka.ms/vs/17/release/vc_redist.x64.exe" -OutFile "C:\vc_redist.x64.exe"; \
    Start-Process -filepath C:\vc_redist.x64.exe -ArgumentList "/install", "/passive", "/norestart" -Passthru | Wait-Process; \
    Remove-Item -Force C:\vc_redist.x64.exe;

More info can be found in this post Loading Microsoft C/C++ DLLs in Windows Containers

SaqlainJanAli commented 5 months ago

This worked for me. Adding Libraries in Dockerfile while deploying.

gbozee commented 5 months ago

Ran into the same problem. The solution was what @kimlehtinen suggested here https://github.com/dotnet/core/issues/4262#issuecomment-1986578346 .

Also ensure using a windowsservercore image because I couldn't install the visual studio c++ executable in the nano base image.