Public | Automated Build

Last pushed: a year ago
Short Description
wkhtmltopdf in a docker container as a web service
Full Description


wkhtmltopdf in a docker container as a rest api web service.

Live demo<br>
User: gooduser<br>
Pass: secretpassword

Running the service

docker build -t pdf-service .
docker run -t -e USER='gooduser' -e PASS='secretpassword' -p pdf-service

Using the webservice via JSON API

Python example

import json
import requests
url = 'https://"+user+":"+pass+"@<docker_host>:<port>/'
data = {
    'contents': open('/file/to/convert.html').read().encode('base64'),
    'options': {
        'margin-right': '20',
        'margin-bottom': '20',
        'page-width': '105mm',
        'page-height': '40mm'
headers = { 'Content-Type': 'application/json', }
response =, data=json.dumps(data), headers=headers)
with open('/path/to/local/file.pdf', 'wb') as f:

Shell example

content=$(echo "<html>Your HTML content</html>" | base64)
footer=$(echo "<html>Your HTML footer</html>" | base64)
curl -vvv -H "Content-Type: application/json" -X POST -d \
    '{"contents": "'"$content"'",
      "options": {
        "margin-top": "20",
        "margin-left": "20",
        "margin-right": "20",
        "margin-bottom": "30"
      "footer": "'"$footer"'"}' \
https://"+user+":"+pass+"@<docker_host>:<port> -o OUTPUT_NAME.pdf

PHP example

$url = 'https://"+user+":"+pass+"@<docker_host>:<port>/';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$body = json_encode([
    'contents' => base64_encode($html),
# print response
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
echo curl_exec($ch);

Additional Options

Payload Size

It might be useful to increase the payload size to allow the generation of larger PDF files in case of errors such as Error: request entity too large. You can configure the payload size limit for the body parser by adding the additional PAYLOAD_LIMIT environment variable to the docker run -t start command. For instance, set the payload limit to 80 megabyte by adding -e PAYLOAD_LIMIT='80mb'. Please consider that a high payload limit might result in high server resource usage and longer response times.


The containing features are easy to disable in case you don't need them. <br> For example disable prometheus metrics:

app.use status()
# app.use prometheusMetrics()
app.use log('combined')
app.use '/', express.static(__dirname + '/documentation')

Auto generated self-hosting documentation (/)

Simple Service Status Overview (/status)

Standard Apache combine format HTTP logging (stdout)

::ffff: - - [11/Sep/2016:14:04:15 +0000] "GET / HTTP/1.1" 200 13500 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.101 Safari/537.36"
::ffff: - - [11/Sep/2016:14:04:15 +0000] "GET /main.css HTTP/1.1" 200 133137 "http://localhost/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.101 Safari/537.36"
::ffff: - - [11/Sep/2016:14:04:16 +0000] "GET /favicon.ico HTTP/1.1" 404 24 "http://localhost/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.101 Safari/537.36"

Prometheus Metrics for service monitoring (/metrics)

# HELP up 1 = up, 0 = not up
# TYPE up gauge
up 1
# HELP nodejs_memory_heap_total_bytes value of process.memoryUsage().heapTotal
# TYPE nodejs_memory_heap_total_bytes gauge
nodejs_memory_heap_total_bytes 29421568
# HELP nodejs_memory_heap_used_bytes value of process.memoryUsage().heapUsed
# TYPE nodejs_memory_heap_used_bytes gauge
nodejs_memory_heap_used_bytes 22794784
# HELP http_request_seconds number of http responses labeled with status code
# TYPE http_request_seconds histogram


The API is protected by basic access authentication. Keep in mind that the basic access authentication mechanism provides no confidentiality protection for the transmitted credentials. The credentials are only base64 encoded, but not encrypted or hashed in any way. The usage of HTTPS is therefore mandatory.


In order to run the test suite you need to first setup the docker container, install the deps and run yarn test:

docker build -t pdf-service .
docker run -t -e USER='gooduser' -e PASS='secretpassword' -p pdf-service
yarn install
yarn test


This Service follows the following design principles

  • horizontal scalability -> stateless
  • don't reeinvent the wheel -> libraries
  • high quality -> 100% code coverage
  • keep it simple stupid (kiss) -> few files, few sloc, no stuff
  • high performance -> non blocking functional asynchronous code


Issues, pull requests and questions are welcome.<br>
The development of the container takes place on
Github.<br>If you have a question or a bug report to file, you can report as a Github issue.

Pull Requests

  • fork the repository
  • make changes
  • if required, write tests covering the new functionality
  • ensure all tests pass and 100% code coverage is achieved (run yarn test)
  • raise pull request
Docker Pull Command