dockersqlitedlldockerfilesystem.data.sqlite

“Unable to load DLL 'SQLite.Interop.dll' or one of its dependencies” running an application in Docker, but locally it works fine


Introduction

There seems to be frequent issues with the SQLite.Interop.dll library. Just look at these other StackOverflow questions:

I’ve gone through all of the above and more:

with no success. The key element is that the application runs just fine locally, but I need to make it run on Docker, and that’s where the problems start. The situation is that I’m working on a .NET Core 3.1 console application with Visual Studio 2022. The application will be finally deployed on AKS (Azure Kubernetes Service). Of course, first I need to make it work on the local installation of Docker in my development machine. Building the console application project on Visual Studio gives me no error and it runs fine from Visual Studio. Building its Docker image with the appropriate Dockerfile also gives no problems, but running the same image on Docker raises the following exception: Unable to load DLL 'SQLite.Interop.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E). Currently, the project has the System.Data.SQLite.Core NuGet package installed and doesn’t have these elements in the *.csproj. The exception is raised by a project referenced by the one of the console application; this project both has the System.Data.SQLite.Core and System.Data.SQLite NuGet packages installed. The console application’s project has only the System.Data.SQLite.Core package installed (I already tried to install also the System.Data.SQLite, with no success). All the projects, now, has the System.Data.SQLite NuGet package installed (to give it a try), which causes the System.Data.SQLite.Core to be installed as a dependency.

What I tried

I used the Dockerfile pre-assembled by Visual Studio 2022, which deals with all the various referenced projects:

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["ProjectA/ProjectA.csproj", "ProjectA/"]
COPY ["ProjectB/ProjectB.csproj", "ProjectB/"]
#COPY all the other referenced projects
RUN dotnet restore "ProjectA/ProjectA.csproj"
COPY . .
WORKDIR "/src/ProjectA"
RUN dotnet build "ProjectA.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "ProjectA.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ProjectA.dll"]

Since this Dockerfile is based on a multi-stage build, it has the following lines:

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

to first build the code, and then publish it. Given that dotnet publish, I decided to take a step back and be sure that, at least, I was able to publish the project myself, to narrow down the issue. I found that publishing it locally on a folder also gave me some problems, in particular the NU1605 error, which was preventing me to end the process successfully. I resolved the issue using what Microsoft suggests. Now, if I run the .exe located inside the publish destination folder, the application works as expected.

It was time to finally make it a Docker image. The image building process went well, but then the Unable... error appeared at runtime. Reading online, to solve the SQLite.Interop.dll issue, they suggest to move the SQLite.Interop.dll file directly in the bin folder; in fact, originally, I found it lived inside the bin\Release\netcoreapp3.1\runtimes\ folder, both in its win-x86 and win-x64 sub-directories. To “get rid” of this runtimes folder, I tried to publish the project locally on a folder, with the following settings:

![enter image description here

This in fact made the SQLite.Interop.dll appear directly inside the bin folder and got rid of the runtimes folder. So, to obtain the same result with Docker, I modified the Dockerfile like this:

...
RUN dotnet build "MyProject.csproj" -c Release -o /app/build -r win-x64
...
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish -r win-x64
...

and now the SQLite.Interop.dll file appears directly also inside the bin folder in the Docker running container, so I thought everything was just fine at that time, but still I got the exception.

One last thing

I found that running the application locally (not in Docker) without specifying the destination runtime (so, keeping the build process as Any CPU instead of x64), raised no exceptions (that is, keeping the runtimes/ folder and the two SQLite.Interop.dll files inside of it, in the win-x86 and win-x64 sub-folders).


Solution

  • I ended up switching to Linux containers.