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
.
Infrastructure¶
Foundation infrastructure:
apt install nginx-extras lua-cjson uwsgi uwsgi-plugin-python
Application¶
Prerequisites¶
Run once to prepare the sandbox environment for deployment tasks:
pip install --requirement requirements-deploy.txt
Deploy application¶
# Define target host for installing package
export PATZILLA_HOST=root@appserver.example.org
# 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¶
Prerequisites¶
System configuration¶
/etc/sysctl.conf:
# 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¶
/etc/uwsgi/apps-available/patzilla-develop.ini:
[uwsgi]
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
Activate:
ln -s /etc/uwsgi/apps-available/patzilla-develop.ini /etc/uwsgi/apps-enabled/
Start:
service uwsgi restart patzilla-develop
Watch:
tail -F /var/log/uwsgi/app/patzilla-develop.log
Web server¶
Nginx configuration¶
/etc/nginx/snippets/ssl-best-practice.conf:
# Contemporary SSL security settings
# https://juliansimioni.com/blog/https-on-nginx-from-zero-to-a-plus-part-2-configuration-ciphersuites-and-performance/
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#ssl_protocols TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECDH+AES256 kEDH+AES128 kEDH+AES256 DES-CBC3-SHA +SHA !aNULL !eNULL !LOW !kECDH !DSS !MD5 !EXP !PSK$
# 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
# http://vincent.bernat.im/en/blog/2011-ssl-session-reuse-rfc5077.html
ssl_session_cache builtin:1000 shared:SSL:20m;
ssl_session_timeout 5m;
location /.well-known {
alias /srv/www/default/htdocs/.well-known;
}
/etc/nginx/conf.d/nginx-auth.conf:
# 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;
/etc/nginx/snippets/patzilla/container.conf:
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;
# http://stackoverflow.com/questions/389456/cookie-blocked-not-saved-in-iframe-in-internet-explorer
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";
}
/etc/nginx/snippets/patzilla/application.conf:
# 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;
# http://docs.pylonsproject.org/projects/waitress/en/latest/#using-behind-a-reverse-proxy
# https://wiki.apache.org/couchdb/Nginx_As_a_Reverse_Proxy
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) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
# to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#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;
/etc/nginx/sites-available/patzilla-develop.example.org:
# webapp via uwsgi
upstream patzilla-develop {
server unix:/run/uwsgi/app/patzilla-develop/socket;
}
server {
server_name patzilla-develop.example.org;
include snippets/patzilla/container.conf;
# SSL: Self-signed
include snippets/snakeoil.conf;
# SSL: Let's Encrypt
#ssl_certificate /etc/letsencrypt/live/patzilla-develop.example.org/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/live/patzilla-develop.example.org/privkey.pem;
error_log /var/log/nginx/patzilla-develop.example.org-error.log info;
location / {
# webapp via uwsgi
uwsgi_pass patzilla-develop;
include snippets/patzilla/application.conf;
}
}
Activate:
ln -s /etc/nginx/sites-available/patzilla-develop.example.org /etc/nginx/sites-enabled/patzilla-develop.example.org
Test and reload:
nginx -t
service nginx reload
Watch:
tail -F /var/log/nginx/patzilla-develop.example.org-*.log
SSL certificates¶
certbot certonly --webroot-path /srv/www/default/htdocs --domains patzilla-develop.example.org --expand
External utilities¶
ImageMagick¶
Introduction¶
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 = [
'/opt/imagemagick-7.0.2/bin/convert',
'/opt/imagemagick/bin/convert',
'/opt/local/bin/convert',
'/usr/bin/convert',
]
Setup¶
Prerequisites:
apt install build-essential libmagickcore-dev libm17n-dev libgif-dev libopenjp2-7-dev libzlcore-dev liblz-dev libltdl-dev libperl-dev
wget http://www.imagemagick.org/download/ImageMagick.tar.gz
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 http://www.imagemagick.org
PDFtk¶
Introduction¶
We definitively want PDFtk >= 2 for joining PDF documents. The software will search for appropriate candidates in this order:
candidates = [
'/opt/pdflabs/pdftk/bin/pdftk',
'/usr/local/bin/pdftk',
'/usr/bin/pdftk',
]
Setup¶
apt install pdftk
pdftk --version
pdftk 2.02 a Handy Tool for Manipulating PDF Documents
On systems with older PDFtk releases:
wget http://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/pdftk-2.02-src.zip
make -f Makefile.Debian
make -f Makefile.Debian install
Maintenance¶
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¶
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
#wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.7-linux-x86_64.tar.bz2
#cp phantomjs-1.9.7-linux-x86_64/bin/phantomjs /usr/local/bin/
Fonts¶
Tweak PhantomJS for better rendering quality. https://gist.github.com/madrobby/5489174
apt install fontconfig libfontconfig libfreetype6 ttf-xfree86-nonfree ttf-mscorefonts-installer
wget --no-check-certificate https://gist.github.com/madrobby/5265845/raw/edd7ba1f133067afd2bd60ba7d40e684bb852c6c/localfonts.conf
mv localfonts.conf /etc/fonts/local.conf