Introduction
There seems to be frequent issues with the SQLite.Interop.dll
library. Just look at these other StackOverflow questions:
- Unable to load DLL 'SQLite.Interop.dll'
- Visual Studio C# – SQLite.Interop.dll not found
- "Unable to load DLL 'SQLite.Interop.dll' error on client machine
I’ve gone through all of the above and more:
- I installed the
System.Data.SQLite.Core
NuGet package, - I specified these elements in the
*.csproj
, - I set
x64
instead ofAny CPU
, - and so on
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 binReleasenetcoreapp3.1runtimes
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:
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).
3
Answers
I ended up switching to Linux containers.
Solution
To run a dotnet application (e.g.
dotnet test
) inside a windows docker container with theSystem.Data.SQLite.Core
nuget package you can use the following docker fileHere is the releveant part of my csproj file:
What worked for me
After switching to the script method, to install the .NET framework (and not using the binary) it worked for me.
Beforehand, like you, I tried a ton of different things!
What you can try
What might work is also to add the
PrivateAssets="none"
in the csproi. See this answer. After adding this to the csproj files I got a different error, because I must use a x86-dll in my project.After installing .NET 6 x86 correctly, I reverted even this change in the csproj and it still worked!
What else
What I also tried, but was not necessary in the end, was Microsoft Visual C++ Runtime Library.
Quote from https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
More information on How-To install .NET in a docker container can be found at the dotnet-docker github repo
TL/DR
Use
dotnet-install.ps1
in your dockerfile to install .NET and the SDK. Somehow, it does some magic, so that you can run dotnet apps which are using theSQLite.Interop.dll
library (included via nuget)We have experienced the issue updating from System.Data.SQLite.Core 1.0.113.6 to 1.0.117.
Locally and in build pipeline everything works fine, but as soon as our app deployed in a docker container running mcr.microsoft.com/dotnet/runtime:6.0-nanoserver-1809 image – application throws the named exception
Unable to load DLL 'SQLite.Interop.dll': The specified module could not be found.
I found this thread at sqlite forum which clarified the situation a bit: https://sqlite.org/forum/info/0c471ca86ae7a836
Quote from the forum:
We ended up reverting back to version 1.0.113.6 as we didn’t want to introduce extra complexity to docker image. I hope the issue with the latest System.Data.SQLite.Core will be resolved in one of the coming versions.