Docker pdfgen

I recently upgraded my full local development environment from phpenv to docker. This allows me to mimic production environments much better and test installations with multiple instances of a single service. It also helps alot to test disater senarios where a service is no longer reachable.
In the process of cleaning my project folder I discovered a PDF generator service I often use to generate PDF documents from webpages. This looked like a greate time to convert this service to it's own docker image, allowing me to install the exact same service on my workstation and on production installations.

Development

API design

The old version had a rather problematic design. It was based on GET parameters with where hardcoded in the installation to get mapped to the wkhtmltopdf cli application.
I chose for a more flexible approach so I coverted the parameters to a json object, allowing any parameter supporting older and newer versions.

old

$ curl \
    -H "Accept: application/pdf" \
    -H "Content-type: application/json" \
    http://pdfgen.dev:80/?url=https://www.google.com&no-background=true

new

$ curl \
    -H "Accept: application/pdf" \
    -H "Content-type: application/json" \
    -X POST \
    -d '{"source": {"url": "https://www.google.com"},"options": {"no-background": true}}' \
    http://192.168.99.100:80/

Application

I chose the silex php framework because of it low footprint. For the wkhtmltopdf wrapper I used knplabs/knp-snappy as it is continuously improved.

Docker

All that remains is creating an image to run the application. The first step is to decide what image to start from. I chose php:5.6-apache as it is a perfect fit. I might use the php:5.6-cli image in a later itteration when converting the application to reactphp.

After resolving all wkhtmltopdf's dependencies I came up with the following Dockerfile:

FROM php:5.6-apache

MAINTAINER Dries De Peuter <dries@nousefreak.be>

RUN apt-get update \
    && apt-get install -y \
        fontconfig \
        xfonts-75dpi \
        libxrender1 \
        xfonts-base \
        libjpeg62-turbo \
        libxext6 \
        git \
        wget \
    && wget -O wkhtmltox.deb http://download.gna.org/wkhtmltopdf/0.12/0.12.2.1/wkhtmltox-0.12.2.1_linux-jessie-amd64.deb \
    && dpkg -i wkhtmltox.deb

RUN sed -i 's|DocumentRoot /var/www/html|DocumentRoot /var/www/html/web|' /etc/apache2/apache2.conf \
    && echo "FallbackResource /index.php" >> /etc/apache2/apache2.conf

COPY . /var/www/html

RUN php -r "readfile('https://getcomposer.org/installer');" | php \
	&& php composer.phar install -o \
	&& rm composer.phar

RUN apt-get purge -y \
        wget \
        git \
    && apt-get clean

The next step was to distribute the package. The simplest option is to tag your image and push it. This means remembering to do this every time I change something. When I created my account no hub.docker.com I quickly discovered automated builds. These allow you to point to an external repo on Github of Bitbucket. They even setup the correct webhooks to trigger builds when the code changes. I create the repository and pushed my installation. After a few minutes the build started and the image was publicly available.

Using it

To start using the server run the follwing command:

$ docker run -d -p 80:80 nousefreak/pdfgen

This will pull the image if you don't have it yet. After the download is finished it will run the image with the -d and -p 80:80 options. These options start the container in daemon mode and forward port 80 on the host to port 80 on the container.

Test

All that is left is to test if it works.
The following command will call the API and request a pdf of google's homepage (without background).

$ curl \
    -H "Accept: application/pdf" \
    -H "Content-type: application/json" \
    -X POST \
    -d '{"source": {"url": "https://www.google.com"},"options": {"no-background": true}}' \
    http://192.168.99.100:80/ > google.pdf

After opening the pdf you should see a printout of the google homepage.


Fork me on GitHub