DinkToPdf
DinkToPdf copied to clipboard
Unable to load assembly in container environment
I have a .Net 2.2 core application that I'm trying to move into a container and I'm having little success getting the assembly loaded. I'm curious has anyone attempted this with any success? I have been hung up on an ELF header error for two days now :
"System.DllNotFoundException: Unable to load shared library '/app/libwkhtmltox.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: /app/libwkhtmltox.dll: invalid ELF header"
Details :
-
Its a 64-bit container image (Debian 9). It's worth pointing out I'm currently using microsoft/dotnet:2.2-aspnetcore-runtime and I have tried :
- mcr.microsoft.com/dotnet/core/runtime:2.2
- mcr.microsoft.com/dotnet/core/runtime:2.2-stretch-slim
- mcr.microsoft.com/dotnet/core/runtime:2.2-bionic
- mcr.microsoft.com/dotnet/core/runtime:2.2.7-bionic
-
The app is built/published on the same flavor of Linux
-
The 64-bit DLL is in the apps working directory as is the dylib and so (see the file sizes in my screenshot)
-
libgdiplus is already present on the Debian 9 base image (it's in my Dockerfile regardless)
-
I'm installing all of the dependencies I could find in the various older issues..
- libx11-6
- libxext6
- libxrender1
- zlib1g
- fontconfig
- libfreetype6
- libgdiplus
- libxcb1
- xfonts-75dpi
- xfonts-base
-
The Deb package for wkhtmltox is being installed.
-
libwkhtmltox.dll is also copied into /usr/lib.
I think the above covers every fix i have found on past issues for loading the dll on ubuntu and container environments, although I want to say none of those were 2.2Core
The relevant part of the C# looks like so :
private SynchronizedConverter Converter
{
get
{
if (_converter == null)
{
var context = new CustomAssemblyLoadContext();
var wkHtmlToPdfPath = Path.Combine(AppContext.BaseDirectory, $@"libwkhtmltox.dll");
Console.WriteLine($"Path to the file : {wkHtmlToPdfPath}");
try
{
context.LoadUnmanagedLibrary(wkHtmlToPdfPath);
}
catch (Exception e)
{
Console.WriteLine("This is where the trouble starts...");
Console.WriteLine(e.ToString());
Console.WriteLine(e.InnerException.Message.ToString());
}
_converter = new SynchronizedConverter(new PdfTools());
}
return _converter;
}
}
Which of course throws an exception :
Loaded '/app/DinkToPdf.dll'. Cannot find or open the PDB file. Path to the file : /app/libwkhtmltox.dll This is where the trouble starts... Loaded '/usr/share/dotnet/shared/Microsoft.NETCore.App/2.2.7/System.IO.MemoryMappedFiles.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. System.DllNotFoundException: Unable to load shared library '/app/libwkhtmltox.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: /app/libwkhtmltox.dll: invalid ELF header at System.Runtime.Loader.AssemblyLoadContext.InternalLoadUnmanagedDllFromPath(String unmanagedDllPath) at System.Runtime.Loader.AssemblyLoadContext.LoadUnmanagedDllFromPath(String unmanagedDllPath) at FormsService.ServiceInterface.Common.HTMLToPDFConverter.get_Converter() in /src/FormsService.ServiceInterface/Common/IHTMLToPDFConverter.cs:line 21
My Dockerfile, which has gone through countless permutations over the last 12 hours or so now looks like :
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 51950
EXPOSE 44378
FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY ["FormsService/FormsService.csproj", "FormsService/"]
COPY ["FormsService.ServiceModel/FormsService.ServiceModel.csproj", "FormsService.ServiceModel/"]
COPY ["FormsService.ServiceInterface/FormsService.ServiceInterface.csproj", "FormsService.ServiceInterface/"]
RUN dotnet restore "FormsService/FormsService.csproj"
COPY . .
WORKDIR "/src/FormsService"
RUN dotnet build "FormsService.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "FormsService.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
RUN apt-get update \
&& apt-get install -y zlib1g fontconfig libfreetype6 \
libx11-6 libxext6 libxrender1 \
libgdiplus libxcb1 xfonts-75dpi \
xfonts-base wget \
&& wget -nv -O /tmp/wkhtmltox.deb https://downloads.wkhtmltopdf.org/0.12/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb \
&& apt-get -qy install /tmp/wkhtmltox.deb \
&& cp /usr/local/bin/wkhtmlto* /usr/bin/ \
&& curl -o /usr/lib/libwkhtmltox.so \
--location \
https://github.com/rdvojmoc/DinkToPdf/blob/master/v0.12.4/64%20bit/libwkhtmltox.so?raw=true \
&& curl -o /usr/lib/libwkhtmltox.dylib \
--location \
https://github.com/rdvojmoc/DinkToPdf/blob/master/v0.12.4/64%20bit/libwkhtmltox.dylib?raw=true \
&& curl -o /usr/lib/libwkhtmltox.dll \
--location \
https://github.com/rdvojmoc/DinkToPdf/blob/master/v0.12.4/64%20bit/libwkhtmltox.dll?raw=true \
&& cp /usr/lib/libwkhtmltox* /app \
&& cp /usr/lib/libwkhtmltox* /app/Dependencies/64Bit/
ENTRYPOINT ["dotnet", "FormsService.dll"]
I added the steps to re-download the Dll/So/Dylib on the off chance that I had some corrupt version locally. Alas this had no effect...
Does anyone have any insight into what the underlying issue maybe? I'm assuming the ELF Header is signaling that a dependency is missing or that dependency is the incorrect arch (32-bit) but I'm grasping at straws at this point.
I have the exactly same error on centos 7,which working nicely in loacl windows 10, but occur the error when I publish my app to the centos 7 server. please tell me how to solve this fxxking problem... thanks
@oscartorres9 I haven't come up with anything yet, still plodding away at it though and if I do come up with a solution for mine ill share it here. I take it you have checked the obvious things - like you don't have a 32bit version of the dll in the directory?
@jxmoore I fix it last night finally. 1.put all the dlls in the root path just with your app, don't create a new folder to put those 3 dlls. 2.When I luanch my webapp on centos 7, it could not render the chinese characters correctly, whitch render as a square, and I solve this by installing chinese font support and uploading font files. finally, this fxxking problem gong..
@oscartorres9 Any chance you could post your DockerFile? I am having trouble with this too.
I fixed my issue, it was entirely my fault. While im not using CentOS i'm still using Dink in the container and loading in some external fonts, so heres my Dockerfile if it helps ya out @codingbadger (or anyone else) :
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0 AS base
RUN apt-get update && apt-get install -y locales && locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
WORKDIR /app
EXPOSE 5000/tcp
ENV ASPNETCORE_URLS=http://+:5000
FROM mcr.microsoft.com/dotnet/core/sdk:3.0-bionic AS build
WORKDIR /src
COPY ["FormsService/FormsService.csproj", "FormsService/"]
COPY ["FormsService.ServiceModel/FormsService.ServiceModel.csproj", "FormsService.ServiceModel/"]
COPY ["FormsService.ServiceInterface/FormsService.ServiceInterface.csproj", "FormsService.ServiceInterface/"]
RUN dotnet restore "FormsService/FormsService.csproj"
COPY . .
WORKDIR "/src/FormsService"
RUN dotnet build "FormsService.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "FormsService.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
# PDF Stuff
RUN apt-get update \
&& apt-get install -y zlib1g fontconfig libfreetype6 \
libx11-6 libxext6 libxrender1 \
libgdiplus libxcb1 xfonts-75dpi xfonts-base \
&& curl -o /app/libwkhtmltox.so \
--location \
https://github.com/rdvojmoc/DinkToPdf/blob/master/v0.12.4/64%20bit/libwkhtmltox.so?raw=true \
&& mkdir ~/.fonts \
&& cp Dependencies/Fonts/* ~/.fonts \
&& mkdir -p /usr/share/fonts/truetype \
&& mv Dependencies/Fonts/* /usr/share/fonts/truetype \
&& fc-cache -fv
ENTRYPOINT ["dotnet", "FormsService.dll"]
Thanks for posting @jxmoore! Unfortunately for me, I am still having no joy with this :( Very frustrating indeed.
Installing the dependencies in @jxmoore's Dockerfile fixed it for me:
apt-get update \
&& apt-get install -y zlib1g fontconfig libfreetype6 \
libx11-6 libxext6 libxrender1 \
libgdiplus libxcb1 xfonts-75dpi xfonts-base
Wanted to share my docker setup. I have managed to setup DinkToPdf in docker with 0.12.5 libwkhtmltox version. I used this https://github.com/Surnet/docker-wkhtmltopdf docker image as a source of dynamic lib and all its dependencies and patched version of DinkToPdf from https://github.com/rdvojmoc/DinkToPdf/pull/72
FROM surnet/alpine-wkhtmltopdf:3.10-0.12.5-full as wkhtml_base
RUN mv /bin/libwkhtmltox.so /usr/lib
# preparing build layer as usual
FROM build as test
COPY --from=wkhtml_base / /
dotnet test
Wanted to share my docker setup. I have managed to setup DinkToPdf in docker with 0.12.5 libwkhtmltox version. I used this https://github.com/Surnet/docker-wkhtmltopdf docker image as a source of dynamic lib and all its dependencies and patched version of DinkToPdf from #72
FROM surnet/alpine-wkhtmltopdf:3.10-0.12.5-full as wkhtml_base RUN mv /bin/libwkhtmltox.so /usr/lib # preparing build layer as usual FROM build as test COPY --from=wkhtml_base / / dotnet test
@artemutin hi can you help me? i do not know how build netcore project image with wkhtmltopdf
@ClementeGao Hi. What is exactly the problem you're facing? Can you share more details, maybe your Dockerfile you're currently writing?
What worked for me was to install wkhtmltopdf with apt (worked on ubuntu, but resulted in a big docker image) or use the correct binary from here, download with wget, install the .deb file with dpkg, which results in an error and then use apt-get -f install -y
to correctly install it.
Here is my dockerfile to build and deploy an asp.net core app to heroku which uses wkhtmltopdf (the images used are based on debian 10):
# NuGet restore
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY ["{your_solution}/{your_project}.csproj", "{your_project}/"]
RUN dotnet restore "{your_project}/{your_project}.csproj"
COPY . .
# publish
WORKDIR "/src/{your_project}"
RUN dotnet publish "{your_project}.csproj" -c Release -o /app/publish
# release
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS release_base
WORKDIR /tmp
# Add wkhtmltopdf and its depoendencies
RUN apt-get update \
&& apt-get install -y wget \
&& wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb \
&& dpkg -i ./wkhtmltox_0.12.6-1.buster_amd64.deb \
; apt-get -f install -y \
&& rm wkhtmltox_0.12.6-1.buster_amd64.deb \
&& rm -rf /var/cache/apt/lists/*
FROM release_base AS release
WORKDIR /app
COPY --from=build /app/publish .
# Run the image as a non-root user
RUN useradd -m myuser
USER myuser
# heroku uses the following
CMD ASPNETCORE_URLS=http://*:$PORT dotnet {your_project}.dll