Setting up WKHTMLTOPDF on Docker Alpine Linux
Reporting in from Vlasotince, a small sunny town in South Serbia. I haven't written in a long, looong time but a vacation morning coffee seemed like a perfect moment to write up a tutorial on how to setup wkhtmltopdf on Docker Alpine distros.
If you ever worked on an e-commerce project you know that generating invoices is an integral part of it. I’ve recently started working on one, and my framework of choice was Sylius which is built on top off PHP’s Symfony framework. Sylius offers an out of the box invoicing system as a plugin which uses KnpSnappy bundle, which on the other hand has wkhtmltopdf as a dependency for generating PDF invoices.
This project has been a twofold learning experience for me as I haven’t worked with either Sylius / Symfony (I was mostly Laravel based) or Docker before.
Admittedly, I’m a bit late on joining the docker / containerisation train, but here I am none the less and I can see it’s benefits and pitfalls already. Since I’m a greenly I struggled with setting up wkhtmltopdf and some of it’s dependencies or at least finding good tutorials / SO posts on how to set it up. My first impression with documentation and tutorials in the Docker system could be best expressed with a metaphor - “It has great unit tests but it lacks in the integration department”.
If you are using Sylius like me you might have seen cryptic errors like The process has been signaled with signal "11" when trying to download or email an invoice. After struggling for a couple of days I finally put all pieces of the puzzle together. There are most probably other ways of doing this buy this is how I did it:
In the PHP container, or the container for your language of choice, install wkhtmltopdf and it's dependencies and give the installed binary permissions to be executed by adding the following commands in your Dockerfile:
FROM php:${PHP_VERSION}-fpm-alpine AS sylius_php
# persistent / runtime deps
RUN apk add --no-cache \
wkhtmltopdf \
xvfb \
ttf-dejavu ttf-droid ttf-freefont ttf-liberation \
;
RUN ln -s /usr/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf;
RUN chmod +x /usr/local/bin/wkhtmltopdf;
Let's break down what we are doing here. The first command installs wkhtmltopdf and it's dependencies:
- xvfb is a server for machines without physical display and input device e.g. our container and is needed for wkhtmltopdf to run properly
- ttf-dejavu, ttf-droid, ttf-freefont, ttf-liberation are all font packages needed by wkhtmltopdf to render the PDF properly, you might be experiencing black box instead of letters issue if you are missing some. You might not necessarily need all of these it depends which font families are you using in you invoices
Also make sure that wkhtmltopdf has 1777 permissions to the folder where it writes the temp files. By default that should be the `/tmp` folder which already has the 1777 permissions on UNIX based systems.
If you want to change that folder in a Sylius project you can do it by changing the knp_snappy.yml config file:
knp_snappy:
temporary_folder: "%kernel.cache_dir%/snappy"
Just make sure the permissions are properly set.
That should be it, if you have any questions you can always ping me on twitter @blackcat_dev.