DinkToPdf icon indicating copy to clipboard operation
DinkToPdf copied to clipboard

Unable to load assembly in container environment

Open jxmoore opened this issue 4 years ago • 11 comments

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 :

details

  1. 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
  2. The app is built/published on the same flavor of Linux

  3. The 64-bit DLL is in the apps working directory as is the dylib and so (see the file sizes in my screenshot)

  4. libgdiplus is already present on the Debian 9 base image (it's in my Dockerfile regardless)

  5. 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
  6. The Deb package for wkhtmltox is being installed.

  7. 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.

jxmoore avatar Oct 30 '19 16:10 jxmoore

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 avatar Oct 31 '19 05:10 oscartorres9

@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 avatar Oct 31 '19 16:10 jxmoore

@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 avatar Nov 01 '19 01:11 oscartorres9

@oscartorres9 Any chance you could post your DockerFile? I am having trouble with this too.

codingbadger avatar Nov 29 '19 18:11 codingbadger

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"]

jxmoore avatar Nov 29 '19 19:11 jxmoore

Thanks for posting @jxmoore! Unfortunately for me, I am still having no joy with this :( Very frustrating indeed.

codingbadger avatar Dec 02 '19 18:12 codingbadger

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

tjeerdhans avatar Mar 19 '20 10:03 tjeerdhans

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

artemutin avatar Apr 05 '20 02:04 artemutin

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 avatar Jun 18 '20 13:06 ClementeGao

@ClementeGao Hi. What is exactly the problem you're facing? Can you share more details, maybe your Dockerfile you're currently writing?

artemutin avatar Jun 22 '20 00:06 artemutin

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

mKay00 avatar Aug 10 '20 10:08 mKay00