Unable to load shared library 'kernel32.dll' - docker

I'm running a dotnet webapp in my local (windows machine) and it works just fine. When I deploy the same application to an AKS container and try running it, it fails with
System.TypeInitializationException: The type initializer for 'System.Runtime.Caching.MemoryMonitor' threw an exception.
---> System.DllNotFoundException: Unable to load shared library 'kernel32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libkernel32.dll: cannot open shared object file: No such file or directory
at Interop.Kernel32.GlobalMemoryStatusEx(MEMORYSTATUSEX& lpBuffer)
at System.Runtime.Caching.MemoryMonitor..cctor()
--- End of inner exception stack trace ---
Below is my Docker
FROM mcr.microsoft.com/dotnet/aspnet:5.0-bullseye-slim
RUN apt-get update && apt-get install -y \
curl
WORKDIR /app
EXPOSE 80
EXPOSE 443
COPY . .
ENTRYPOINT ["dotnet", "MyApp.dll"]
Let me know if anyone has solved or seen this before

It looks like you're copying in your binaries directly into the container. The tag you are using is 5.0-bullseye-slim is Linux-based. So if the binaries you're copying in were built for the Windows platform, which I'm guessing they are since it's looking for kernel32.dll, then that's not going to run in a Linux environment.
You'll either need to build your binaries so that they are targeting Linux, which can be done with dotnet build -r linux-x64 ..., or a better option would be to build your project as part of the Dockerfile.
Here's an example Dockerfile that demonstrates this:
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /source
# copy csproj and restore as distinct layers
COPY *.csproj .
RUN dotnet restore
# copy and publish app and libraries
COPY . .
RUN dotnet publish -c release -o /app --no-restore
# final stage/image
FROM mcr.microsoft.com/dotnet/runtime:6.0
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "dotnetapp.dll"]
(Taken from
https://github.com/dotnet/dotnet-docker/blob/0fc0e2c6af6303cfd4676f1ac8c21090d82b0072/samples/dotnetapp/Dockerfile)

Related

Docker Container ODBC connection to External SQL Server

I'm attempting to run my ASP NET Core 3.1 API in a Linux Docker container. A component in my API requires a connection via ODBC to a server located on an external server. While in debug mode when I startup my API, the connection is attempted via ODBC but fails with the error "libodbc could not be loaded" I assume the ODBC drivers are missing in the Docker container.
I have searched online and I haven't been able to find how I would go about adding the missing library to my container or if maybe I need to download a different Base image. A copy of my docker file can be found below.
FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["Sample.Service/Sample.Service.csproj", "Sample.Service/"]
COPY ["../Libs/ExternalServices.Configure/ExternalServices.Configure.csproj", "../Libs/ExternalServices.Configure/"]
RUN dotnet restore "Sample.Service/Sample.Service.csproj"
COPY . .
WORKDIR "/src/Sample.Service"
RUN dotnet build "Sample.Service.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Sample.Service.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Sample.Service.dll"]
After looking deeper into the problem, I was missing a couple of key things to make it work. I did need to add the Linux commands to ensure the repositories are updated and then make a request to install the unixodbc library. The resulting Docker file looks like this.
FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
RUN apt-get update
RUN apt-get install -y unixodbc
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["Sample.Service/Sample.Service.csproj", "Sample.Service/"]
COPY ["../Libs/ExternalServices.Configure/ExternalServices.Configure.csproj", "../Libs/ExternalServices.Configure/"]
RUN dotnet restore "Sample.Service/Sample.Service.csproj"
COPY . .
WORKDIR "/src/Sample.Service"
RUN dotnet build "Sample.Service.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Sample.Service.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Sample.Service.dll"]

"An assembly specified in the application dependencies manifest was not found" using docker

I am trying to dockerize an an angular aspnet core 2.2 webapi using the following dockerfile:
FROM mcr.microsoft.com/dotnet/core/sdk:2.2.105 AS build
WORKDIR /src
# Copy csproj and restore as distinct layers
COPY ["Fightplan_v1/Fightplan_v1.csproj", "Fightplan_v1/"]
COPY ["Fightplan_v1.Autogenerate/Fightplan_v1.Autogenerate.csproj", "Fightplan_v1.Autogenerate/"]
COPY ["Fightplan_v1.Autogenerate.Test/Fightplan_v1.Autogenerate.Test.csproj", "Fightplan_v1.Autogenerate.Test/"]
COPY ["Fightplan_v1.Database/Fightplan_v1.Database.csproj", "Fightplan_v1.Database/"]
COPY ["Fightplan_v1.Helpers/Fightplan_v1.Helpers.csproj", "Fightplan_v1.Helpers/"]
COPY ["Fightplan_v1.Jobs/ConvertImagestoBlob/Fightplan_v1.ConvertImagestoBlob.csproj", "Fightplan_v1.Jobs/ConvertImagestoBlob/"]
COPY ["Fightplan_v1.Models/Fightplan_v1.Models.csproj", "Fightplan_v1.Models/"]
COPY ["Fightplan_v1.Shared/Fightplan_v1.Shared.csproj", "Fightplan_v1.Shared/"]
RUN dotnet restore "Fightplan_v1/Fightplan_v1.csproj"
# Copy everything else and build
COPY . .
WORKDIR "/src/Fightplan_v1"
RUN dotnet build "Fightplan_v1.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "Fightplan_v1.csproj" -c Release -o /app
# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime
WORKDIR /app
COPY --from=build /app .
EXPOSE 80
ENTRYPOINT ["dotnet", "Fightplan_v1.dll"]
The build command used is:
docker build -f .\fp.dockerfile -t test .
The build goes through fine but when I try to run it using:
docker run -p 5100:80 -it test
I get the following error:
I have tried:
Adding -r linux-x64 to the end of publish to define the runtime: RUN dotnet publish "Fightplan_v1.csproj" -c Release -o /app -r linux-x64
Adding <PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest> to my .csproj file
None of the above fixes work unfortunately.
Since this is combined poject of an angular application and a webapi I might be missing some installations/dependencies?
You are copying the runtime files from wrong layer
COPY --from=build /app .
Try to change it to
COPY --from=publish /app .
Also, you probably need to separate out path in build and publish steps:
RUN dotnet build "Fightplan_v1.csproj" -c Release -o /app/build
RUN dotnet publish "Fightplan_v1.csproj" -c Release -o /app/publish
and then copy runtime files from the publish folder
COPY --from=publish /app/publish .
Edit. Basically, you need to copy publish artifacts into runtime, not build. Build will produce deps.json, which will lists all external dependencies, and during runtime this libraries are resolving using NuGet cache, if it is empty you will see an error. To copy dependencies along with project files you need to run publish.
So I assume, that theoretically dotnet build can be omitted, and is using only to discover compilation errors on early stage of docker build.

Unable to load DLL 'activeds.dll'

I know this question was asked but nobody answer it.
I'm building web API on Core 2.2 with JWT token bearer. In token request I added check if user exist on our LDAP.
All working properly on IIS and console app but when I run with docker I'm getting:
"Unable to load DLL 'activeds.dll' or one of its dependencies: The specified module could not be found. (Exception from HRESULT: 0x8007007E)"
error.
If user exist all working fine but when user not exist Im checking user status with:
UserPrincipal oUserPrincipal = UserPrincipal.FindByIdentity(oPrincipalContext, sUserName);
Which causing error above.
Im new to docker. I have tried to play with images:
mcr.microsoft.com/dotnet/core/sdk
mcr.microsoft.com/dotnet/core/aspnet
microsoft/aspnetcore-build
In all cases the same result
I have exposed LDAP ports in docker file (or I think I exposed) and still getting the same error.
My current dockerfile:
FROM mcr.microsoft.com/dotnet/core/sdk AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 383
EXPOSE 636
FROM mcr.microsoft.com/dotnet/core/sdk AS build
WORKDIR /src
COPY ["USITWebApi/USITWebApi.csproj", "USITWebApi/"]
RUN dotnet restore "USITWebApi/USITWebApi.csproj"
COPY . .
WORKDIR "/src/USITWebApi"
RUN dotnet build "USITWebApi.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "USITWebApi.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "USITWebApi.dll"]
I'm using Windows containers.
I spent three days trying to solve this. If you have any ideas please help me solve this issue.
Looks that it is a limitation based on the image that you are using as base. If you would like to use LDAP use any server core image based on your host OS. This is what I am doing. This is a example for Windows 2019 Server as host.
FROM mcr.microsoft.com/windows/servercore:ltsc2019 AS base
WORKDIR /app
EXPOSE 80
RUN powershell Set-ExecutionPolicy RemoteSigned
RUN powershell iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
RUN powershell choco install dotnet-6.0-runtime -Y
RUN powershell choco install dotnet-6.0-sdk -y
ENV ASPNETCORE_URLS=http://+80
RUN powershell fsutil behavior set symlinkEvaluation L2L:1 L2R:1 R2R:1 R2L:1
RUN powershell Set-ExecutionPolicy Bypass -Scope Process
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["src/Your.ProjectFile.csproj", "src/Your.Project.Folder/"]
COPY ["./NuGet.Config", "src/Your.Project.Folder"]
RUN dotnet restore "src/Your.Project.Folder/Your.ProjectFile.csproj"
COPY . .
WORKDIR "/src/src/Your.Project.Folder"
RUN dotnet build "Your.ProjectFile.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Your.ProjectFile.csproj" -c Release -o /app/publish
FROM base
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Your.ProjectFile.dll"]

How to copy a csproj file using docker without visual studio and without docker compose?

I just started a new solution with a .NET Core Project (2.1) using visual studio 15.8.8. It can run and debug it by setting the docker compose file as a startup project. It works!
Logically, I should be able to build the docker image with a simple commandline statement. However, it complains that the csproj cannot be found. This is strange. The file exist and as I told, I can run it from visual studio. I tried it from one directory up and the directory that has the dockerfile. Same problem.
How can I solve this? The only thing I want is simply build my image and then run it by just using docker commands.
Dockerfile
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY ["TryNewDocker2/TryNewDocker2.csproj", "TryNewDocker2/"]
RUN dotnet restore "TryNewDocker2/TryNewDocker2.csproj"
COPY . .
WORKDIR "/src/TryNewDocker2"
RUN dotnet build "TryNewDocker2.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "TryNewDocker2.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TryNewDocker2.dll"]
Het is the compose file:
version: '3.4'
services:
trynewdocker2:
image: ${DOCKER_REGISTRY}trynewdocker2
build:
context: .
dockerfile: TryNewDocker2/Dockerfile
Logically, I want "docker-compose up" to keep working when fixing this problem.
This is caused by the wrong root folder for the file path in dockerfile.
For launching from Docker, its root folder is C:\Users\...\repos\TryNewDocker2, but while running from command, its root fodler is C:\Users\...\repos\TryNewDocker2\TryNewDocker2, so the path for TryNewDocker2.csproj has changed from TryNewDocker2/TryNewDocker2.csproj to TryNewDocker2.csproj
Try dockerfile below:
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 59162
EXPOSE 44342
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY ["TryNewDocker2.csproj", "TryNewDocker2/"]
RUN dotnet restore "TryNewDocker2/TryNewDocker2.csproj"
COPY . ./TryNewDocker2/
WORKDIR "/src/TryNewDocker2"
RUN dotnet build "TryNewDocker2.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "TryNewDocker2.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TryNewDocker2.dll"]
Update
For working in both Docker and command, do not change your dockerfile, and from path below to run your command with specifying the dockerfile path.
C:\Users\...\repos\TryNewDocker2>docker build -t gogo -f TryNewDocker2/Dockerfile .
For those of you who end up here years later like I did, I'll share my experience.
My problem was caused by the auto-generated Dockerfile that came from Visual Studio's "add > Docker Support..." was on the same level as my .csproj file.
The specific line causing me trouble was COPY ["MyApp/MyApp.csproj", "MyApp/"] which should have been just COPY ["MyApp.csproj", "MyApp/"]. Removing the extra MyApp/ in front of the .csproj got the build working fine.
Special thanks to Edward in the answer above for pointing me in the right direction.

Docker and VS Mac

Following the instructions on Docker's page I created a very simple Dockerfile that looks like this:
FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "dockertest.dll"]
This is literally a copy of the sample on Docker's site just changed the application name.
I used Visual Studio for Mac to create a very simple ASP.Net application (actually, just the default app with a tiny HTML file added in).
When I first ran docker build -t dockertest . the line with dotnet publish failed. I then ran the dotnet publish manually and got past that.
It now fails on the copy:
Step 9/10 : COPY --from=build-env /app/out .
COPY failed: stat /var/lib/docker/overlay2/1484306cebf1def83638270757e70a8cf874fb5a167f39e5bfaae92a47cc071c/merged/app/out: no such file or directory
What's going on?
So did you run dotnet publish inside the container or on the host machine? The Docker file is trying to run those commands inside the container, so running those on the host will not fix the issue.
Have you tried to right click your project and "Add Docker Support" to your app in VS for Mac? It should generate a docker file and then you can run/debug your app inside the container from within VS.

Resources