DinkToPdf in Docker

To generate PDFs from HTML using DinkToPdf in a linux based container, the libwkhtmltox.so library is required.

One way to do this is to simply include libwkhtmltox in your version control system, but it takes up a lot of space (43 MB) thereby increasing the time for initial checkouts considerably. A better way, if your app is containerized, is to let the Dockerfile define how to fetch libwkhtmltox when building the base image for your app.

The following examples are based on the lightweight Debian linux image, more specifically “aspnet:5.0-buster-slim”.

Due to its slimmed down nature, the “aspnet:5.0-buster-slim” image does not even have wget installed, so we will have to install that along with other dependencies needed by wkhtmltopdf. Add the following to the “base” stage in your Dockerfile:

RUN apt update
RUN apt install -y libgdiplus
RUN ln -s /usr/lib/libgdiplus.so /lib/x86_64-linux-gnu/libgdiplus.so
RUN apt-get install -y --no-install-recommends zlib1g fontconfig libfreetype6 libx11-6 libxext6 libxrender1 wget gdebi
RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN gdebi --n wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN ln -s /usr/local/lib/libwkhtmltox.so /usr/lib/libwkhtmltox.so

Libgdiplus is a replacement for System.Drawing required by DinkToPdf to work in a linux environment.

It is important that symbolic links are made to libgdiplus.so and libwkhtmltopdf in /usr/lib. Many examples of getting DinkToPdf to work save the files in the /app directory but this will not work while debugging the dockerized app in Visual Studio. Downloading to the /app dir using wget seems to works without errors when monitoring the build output, but the file simply does not appear in the /app directory in the final image. The reason for this is, that in Visual Studio, the /app directory is a Volume mapped to the directory on the host machine containing the source code. A little gotcha that can take a few hours of debugging to track down 🙂

The following is a complete Dockerfile utilizing the lines from above to enable PDF generation inside a Debian linux based Docker container.

FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app

RUN apt update
RUN apt install -y libgdiplus
RUN ln -s /usr/lib/libgdiplus.so /lib/x86_64-linux-gnu/libgdiplus.so
RUN apt-get install -y –no-install-recommends zlib1g fontconfig libfreetype6 libx11-6 libxext6 libxrender1 wget gdebi
RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN gdebi –n wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN ln -s /usr/local/lib/libwkhtmltox.so /usr/lib/libwkhtmltox.so
ENV ASPNETCORE_URLS=http://+:80
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY [“BooksOnline.PdfService/BooksOnline.PdfService.csproj”, “BooksOnline.PdfService/”]
RUN dotnet restore “BooksOnline.PdfService/BooksOnline.PdfService.csproj”
COPY . .
WORKDIR “/src/BooksOnline.PdfService”
RUN dotnet build “BooksOnline.PdfService.csproj” -c Release -o /app/build

FROM build AS publish
RUN dotnet publish “BooksOnline.PdfService.csproj” -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY –from=publish /app/publish .
ENTRYPOINT [“dotnet”, “BooksOnline.PdfService.dll”]