Production setup

For getting an idea about how to install PatZilla in a production environment. The following documentation is for Debian GNU/Linux 8 (jessie). The designated target directory is /opt/patzilla.


Foundation infrastructure:

apt install nginx-extras lua-cjson uwsgi uwsgi-plugin-python



Run once to prepare the sandbox environment for deployment tasks:

pip install --requirement requirements-deploy.txt

Deploy application

# Define target host for installing package

# Possible targets: develop,staging,prod
make install target=patzilla-develop

# Optionally nail to a specific version
make install target=patzilla-develop version=0.30.0

Upload nginx-auth lua code:

make install-nginx-auth

Application container


System configuration


# The maximum number of "backlogged sockets".  Default is 128.
net.core.somaxconn = 2048

Reload configuration:

sysctl -p

Application configuration

cp /opt/patzilla/sites/patzilla-develop/production.ini.tpl /opt/patzilla/sites/patzilla-develop/production.ini

Edit production.ini according to your needs.

uWSGI configuration


uid = www-data
gid = www-data
processes = 8
listen = 2048
buffer-size = 32768

plugins = python
virtualenv = /opt/patzilla/sites/patzilla-develop/.venv27
paste = config:/opt/patzilla/sites/patzilla-develop/production.ini

paste-logger = true
#sync-log = true


ln -s /etc/uwsgi/apps-available/patzilla-develop.ini /etc/uwsgi/apps-enabled/


service uwsgi restart patzilla-develop


tail -F /var/log/uwsgi/app/patzilla-develop.log

Web server

Nginx configuration


# Contemporary SSL security settings
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#ssl_protocols TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
#ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_dhparam /etc/nginx/ssl/dhparam-4096.pem;

add_header Strict-Transport-Security 'max-age=31536000';
ssl_stapling on;

# enable session resumption to improve https performance
ssl_session_cache builtin:1000 shared:SSL:20m;
ssl_session_timeout 5m;

location /.well-known {
    alias /srv/www/default/htdocs/.well-known;


# Configure Lua package search path
lua_package_path ";;/opt/patzilla/nginx-auth/lua/?.lua;";

# Uncomment this for working on the Lua code
#lua_code_cache off;


set $luadir "/opt/patzilla/nginx-auth/lua";

listen 80;
listen 443 ssl;
#listen 443 ssl spdy;

include snippets/ssl-best-practice.conf;

# individual nginx logs for this vhost
access_log  /var/log/nginx/$host-access.log;

root /srv/www/null;

more_set_headers 'P3P: CP="This site does not have a p3p policy."';

location = "/auth" {
    lua_need_request_body on;
    content_by_lua_file "$luadir/authentication.lua";


# webapp via uwsgi
uwsgi_read_timeout 1500;

# userid gets set by access.lua
set $user_id "";

access_by_lua_file "$luadir/access.lua";

include       uwsgi_params;
uwsgi_param   SCRIPT_NAME                 '';
uwsgi_param   REQUEST_METHOD              $echo_request_method;

# propagate userid to upstream service via http request headers
uwsgi_param   HTTP_X_USER_ID              $user_id;

uwsgi_param   HTTP_X_REAL_IP              $remote_addr;
uwsgi_param   HTTP_X_FORWARDED_PROTO      $scheme;
uwsgi_param   HTTP_X_FORWARDED_FOR        $proxy_add_x_forwarded_for;

#add_header    Content-Security-Policy  "default-src https:; script-src https: 'unsafe-inline' 'unsafe-eval'; style-src https: 'unsafe-inline'";
#add_header    Content-Security-Policy  "script-src 'unsafe-inline' 'unsafe-eval'; style-src https: 'unsafe-inline'";
# config to enable HSTS(HTTP Strict Transport Security)
# to avoid ssl stripping
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";

if ($server_port = 80) {
    #rewrite ^ https://$host$request_uri;
    rewrite (.*) https://$http_host$1;

# pass-through static and api urls
rewrite ^/static/(.*)$ /static/$1 break;
rewrite ^/api/(.*) /api/$1 break;

# rewrite urls to match application
rewrite ^/(.+)$ /navigator/$1 break;
rewrite ^/?(.*)$ /navigator/$1 break;


# webapp via uwsgi
upstream patzilla-develop {
    server unix:/run/uwsgi/app/patzilla-develop/socket;

server {


  include snippets/patzilla/container.conf;

  # SSL: Self-signed
  include snippets/snakeoil.conf;

  # SSL: Let's Encrypt
  #ssl_certificate /etc/letsencrypt/live/;
  #ssl_certificate_key /etc/letsencrypt/live/;

  error_log   /var/log/nginx/ info;

  location / {

    # webapp via uwsgi
    uwsgi_pass        patzilla-develop;

    include snippets/patzilla/application.conf;




ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

Test and reload:

nginx -t
service nginx reload


tail -F /var/log/nginx/*.log

SSL certificates

certbot certonly --webroot-path /srv/www/default/htdocs --domains --expand

External utilities



We found on some systems the convert tool from ImageMagick 6 yields drawings with low quality (contrast, etc.), so you might want to consider installing ImageMagick >= 7. The software will search for appropriate candidates in this order:

candidates = [



apt install build-essential libmagickcore-dev libm17n-dev libgif-dev libopenjp2-7-dev libzlcore-dev liblz-dev libltdl-dev libperl-dev
tar -xzf ImageMagick.tar.gz
cd ImageMagick-7.0.7-31/

./configure --prefix=/opt/imagemagick
make && make install
/opt/imagemagick/bin/convert --version
Version: ImageMagick 7.0.2-6 Q16 x86_64 2016-08-06



We definitively want PDFtk >= 2 for joining PDF documents. The software will search for appropriate candidates in this order:

candidates = [


apt install pdftk
pdftk --version
pdftk 2.02 a Handy Tool for Manipulating PDF Documents

On systems with older PDFtk releases:

make -f Makefile.Debian
make -f Makefile.Debian install


unoconv is used to convert spreadsheet worksheets to PDF documents.

# Debian Linux
apt install unoconv libreoffice


PatZilla is almost maintenance-free. However, there are a few things to take into consideration.

Database backup

Please refer to MongoDB backup about how to make daily backups of the production database.

Database frontend

You might want to have a look at Genghis_ for a user interface to MongoDB. Please follow up at Genghis setup about setup instructions.

Document and query cache

PatZilla caches all responses in the databases with various TTLs to provide a better user experience. If this cache fills up too much, you might want to purge it from time to time:

mongo beaker --eval 'db.dropDatabase();'

You might want to restart the application after that, better safe than sorry.

External utilities - currently not used

These tools are currently not used, but references are kept for future reactivation.


PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.

It is used for rendering PDF documents from HTML.

apt install phantomjs

# Deprecated
#cp phantomjs-1.9.7-linux-x86_64/bin/phantomjs /usr/local/bin/


Tweak PhantomJS for better rendering quality.

apt install fontconfig libfontconfig libfreetype6 ttf-xfree86-nonfree ttf-mscorefonts-installer

wget --no-check-certificate
mv localfonts.conf /etc/fonts/local.conf


Convert drawings in GIF format from CIPO.

apt install libtiff-tools