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

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
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
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
COPY –from=publish /app/publish .
ENTRYPOINT [“dotnet”, “BooksOnline.PdfService.dll”]

HTTPS Redirect with .htaccess

Creating a simple HTTPS redirect rule for Apache can potentially be a long, tiresome journey of trial and error.
There are many ways to write the rule with subtle syntax differences and other factors such as the version of the Apache server also affecting the outcome.
The following snippet is what finally worked for me on Gigahost (a shared web hosting provider in Denmark).

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{ENV:HTTPS} !on
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

XBMC + TVHeadEnd + HDHomeRun


How to install and configure TVHeadend and HDHomerun on an OpenELEC machine.


HDHomerun Driver


Configure HDHomerun Driver

Change directory to /storage/.xbmc/addons/driver.dvb.hdhomerun/config
Make a copy of dvbhdhomerun.sample to dvbhdhomerun.conf

Open \\xbmc\Userdata\addon_data\driver.dvb.hdhomerun\adapters and copy the IDs of the two tuners to dvbhdhomerun and set their types (just follow the instructions in the config file.). Alternatively, run userhdhomerun to get the IDs.


Configure TVHeadend

Go to webpage of TVHeadend: http://:9981
Go to Configuration -> DVB Inputs -> TV Adapters

Select the first adapter.
Click “Add DVB Network by Location”
Choose your location
Click “Enabled”
Click “Save”
TVHeadend now starts scanning for channels. You can monitor its progress in the pane to the right. When “Muxes awaiting initial scan” is zero, it’s done.
Click “Map DVB Services to Channels”.
The mapping will also take some minutes to complete depending on how many channels are present.

In the web config in Configuration -> TV Adapters: After all channels have been configured, disable “Autodetect Muxes” and “Idle Scanning“. Having these enabled completely destroyed the stream from TVHeadEnd, making the image look garbled and stuttering. It looked like a low bandwidth connection or bad signal.

Get XML String from JQuery XML Object

Problem: You have an XML structure in a JQuery object and now you want to extract a string with the raw xml.
Solution: Use the XMLSerializer class. This class provides methods for serializing DOMs and nodes into text or byte streams. In our case, we will call the serializeToString(data) method:

new XMLSerializer().serializeToString(xmlDoc);

Computer Forensics

The tools I use for computer forensics.


  • Recuva – Excellent at recovering data from Windows partitions and free to boot.
  • UFS Explorer – Not free, but is able to recover from linux partitions (Recuva is better for FAT/NTFS)
  • explore2fs – Access linux partitions from Windows. Free.
  • HFSExplorer – Access Mac partitions from Windows


  • Hiren’s Boot CD – Contains an impressive lineup of programs for computer forensics, but its legal status is often debated.
  • Trinity Rescue Kit – A live distro with backup programs, Midnight Commander, testdisk, shell and other good stuff. Legal!

Non-ASCII chars in Java

If you are having problems with non-ASCII characters (for example the Danish æ, ø and å) not showing up correctly in your Java application, try giving the Java VM the following argument:


You can verify that the charset has been set with this statement:


Slow access to shared network folder from VM

After changing the network adapter type on a VMware virtual machine from NAT to bridged, the transfer speed from shared network folders dropped to about 25 kb/s and browsing shared folders was really sluggish. The network folder was located on the host machine, which was running Windows 7 Searching the VMware knowledge base resulted in the following article. I can confirm that the proposed solution also applies to Windows 7:

Performance issues with bridged networking on Windows Server 2003 and Windows 2008 host operating systems

In short: Use regedit to navigate to the following place:


Then create a DWORD key named DisableTaskOffload and give it ‘1’ as value. TCP task offloading means distributing calculations concerning the network communication to the network card, so creating this registry key means that all these calculations will be done on the CPU.
Microsoft Virtual Server seems to be susceptible to the same problem and offers the same solution along with two others: Slow performance when you try to access resources on your Virtual Server 2005 host computer from a guest virtual machine