Seitenmodernität

Vielen Unternehmen gelingt es zeitweise, ihre antiquierten Prozesse hinter einer modernen Fassade zu verbergen, bis sich die triste Realität Bahn bricht. Dieses Schicksal möchte ich meiner frisch renovierten Website ersparen. Das Django-Projekt verweist bereits seit längerer Zeit auf die Zukunft, die allerdings unter OS X und CentOS noch nicht angekommen ist.

Im ersten Schritt werde ich also Python 3 neben der vorhandenen Python-Version (2.6) installieren. Es handelt sich um eine etwas delikate Operation, weil die Betriebssysteme Python für viele interne Abläufe nutzen und durch ein zweites Python nachhaltig verwirrt werden könnten. Daher (CentOS):

./configure --prefix=/usr/local make make altinstall

Für OS X gibt es ein komfortables Installationspaket. Im zweiten Schritt muss der Datenbankkonnektor psycopg2 für Python 3 kompiliert werden (er vermisst pg_config und muss explizit auf dessen Pfad hingewiesen werden). Die Installation einer aktuellen Django-Version erfolgt natürlich im Kontext von Python 3 (python3 setup.py install).

Die Umstellung der Anwendung selbst auf Python 3 ist einfacher als befürchtet – der größte Teil der Anpassungen bezieht sich nicht auf die berüchtigte Unicode/Bytestring-Unterscheidung, sondern auf die geänderte URL-Syntax (urls.py) und verschiedene Einstellungen (settings.py). Lediglich die Funktion make_static stolpert nachhaltig. Nach einigen komplizierten Korrekturversuchen stellt sich heraus, dass ich lediglich ein einziges Zeichen ergänzen muss (html_file = open(file, 'wb')), um alle zu schreibenden Dateien Bytestring-kompatibel zu öffnen. Dass ich vorher zwischen zwei Schreibmodi differenzieren musste, spricht für die verdrehte String-Logik in Python 2.

Beim Deployment möchte ich anders als bisher nicht auf nginx/Apache/mod_wsgi setzen, sondern die Komplexität reduzieren. Django empfiehlt zu diesem Zweck uWSGI. Dessen Konfiguration ist recht simpel:

[uwsgi] master = true socket = /private/tmp/eden.sock touch-reload = /Users/eden/dj/project3/wsgi.py chdir = /Users/eden/dj/project3/ wsgi-file = project3/wsgi.py uid = eden gid = staff processes = 5 threads = 2 stats = 127.0.0.1:9191 buffer-size = 32768 vacuum = true die-on-term = true

Da uWSGI kein Apache-Modul ist, muss es separat gestartet werden. Lokal bastele ich einen LaunchAgent, auf dem Server muss ich mit Upstart experimentieren (was offenbar auch nur eine Übergangslösung auf dem Weg zu systemd darstellt):

description "uwsgi tiny instance" start on runlevel [2345] stop on runlevel [06] respawn exec uwsgi --ini /etc/uwsgi.ini

Überraschend muss auch pg_hba.conf angepasst werden, weil die Authentifizierungsmethode ident für Unix-Sockets nicht akzeptiert wird:

host all all 127.0.0.1/32 md5

Am umfangreichsten sind die Änderungen in nginx.conf. Statt proxy_cache und proxy_pass müssen uwsgi_cache und uwsgi_pass genutzt werden:

uwsgi_cache_valid 1d; uwsgi_cache_path /var/cache/nginx/mysites levels=1:2 keys_zone=mysites:5m inactive=1h max_size=1g; uwsgi_cache_use_stale error timeout invalid_header updating http_500 http_503; uwsgi_cache_key localhost:9000$request_uri; uwsgi_cache statt proxy_cache. server { listen 443 ssl http2; server_name eden.one; uwsgi_cache mysites; location / { uwsgi_pass unix:///tmp/eden.sock; include uwsgi_params; expires 7d; } }

Insgesamt eine lehrreiche Konfontation mit übertriebenen Ängsten und eine schöne Gelegenheit, mich mit meinem alten Python-Code zu beschäftigen. Außerdem verfüge ich jetzt über ein modernes Backend (Python 3.5/Django 1.10) und einen entsprechend ruhigen Nachtschlaf.