Setup 2021

Nach vier Jahren mit einer ausgesprochen empfindsamen Tastatur wechsele ich zu einer solideren Konstruktion und einer leistungsfähigeren Prozessorarchitektur. Letztere lässt mich etwas besorgt auf das Setup-Ritual blicken, denn die letzten Durchgänge waren ziemlich aufwendig.

Homebrew

Der Schlüssel zu einem Setup in Rekordzeit ist der Verzicht auf die relativ plattformunabhängige Low Level-Reproduzierbarkeit einzelner Installationsvorgänge, das heißt: Die Verwendung eines Paketmanagers. Dank Homebrew sind Mailstack (samt GnuPG!) und Webstack innerhalb von Minuten installiert:

brew install mutt brew install offlineimap brew install msmtp brew install w3m brew install nginx brew install postgresql@13

Weil die von Apple gelieferten vim- und rsync-Versionen einige Funktionen vermissen lassen (u.a. den für meine Backup-Strategie zentralen rsync-Parameter --ignore-missing-args) und ich eine Allzweckwaffe zur Textkonversion benötige, folgt:

brew install vim brew install rsync brew install pandoc

Python 3.9 installiere ich zunächst über das Installationspaket für macOS in /Library/Frameworks, bevor mir (gerade noch rechtzeitig) auffällt, dass Homebrew Python 3.9 bereits (als Voraussetzung für vim) in /opt/homebrew/bin platziert hat. Ich entferne das Mac-Python (und die entsprechenden Symlinks in /usr/local/bin) und fahre mit dem Brew-Python fort:

pip3 install Django==3.1.7 brew install uwsgi pip3 install uwsgi

Die doppelte uwsgi-Installation ist eine – nicht vollständig rationale – Verzweiflungstat. Beim manuellem Aufruf (uwsgi --socket /private/tmp/eden.sock --module djangoapp.wsgi --chmod-socket=664) lässt sich uwsgi nämlich durchaus bewegen, meine Django-Applikation auszuliefern, beim Start als launchctl-Job (homebrew.mxcl.uwsgi) wird das Python-Plugin aber erst gefunden, wenn uwsgi.ini ausdrücklich auf Python hinweist (plugins = python3). Und auch nur dann, wenn man der Brew-Installation mit der pip3-Installation nachhilft. Ich muss nicht alles verstehen, obgleich das Deployment-Tutorial die Lieferkette (the web client ←→ the web server ←→ the socket ←→ uwsgi ←→ Django) und mögliche Fehlerquellen eigentlich sehr verständlich darstellt. Für verschiedene Skripte werden einige Python-Module nachinstalliert (pip3 install xxx), und das letzte verbleibende Python 2-Skript wird endlich migriert. In der Django-Applikation muss trotz des Versionssprungs (Django 1.x → Django 3.1.7) nur sehr wenig geändert werden: Das Modul django.core.urlresolvers heißt nun django.urls, und die Klasse ForeignKeys sieht einen zusätzlichen Parameter (on_deletion) vor. Selbst das komplexe Kommando make_static funktioniert auf Anhieb.

Konfiguration

Aus dem Backup übernehme ich die wichtigsten Konfigurationsdateien (mutt, GnuPG, MSMTP, Offlineimap, SSH), so dass der Mailstack völlig ohne Anpassungen in Betrieb genommen werden kann. Wenn man davon absieht, dass ich einen dritten Mail-Account konfiguriere (→ .muttrc, .msmtprc und .offlineimaprc) und etwas länger brauche, um den Wert des Offlineimap-Parameters maxsyncaccounts entsprechend zu erhöhen. Die Migration von bash auf zsh ist erstaunlich einfach (.bash_profile.zshrc), lediglich die Pfadergänzungen aus .bash_profile erhalten eine neue Heimat in .zshenv.

Ebenfalls aus dem Backup werden ~/Library/Scripts, ~/Library/Keychains, ~/Library/LaunchAgents, ~/Library/texmf und einige Ordner in ~/Library/Application Support übernommen. Dank Homebrew lassen sich die LaunchAgents für PostgreSQL, Offlineimap und nginx ohne selbstgeschriebene property files verwalten (brew services start|stop postgresql|offlineimap|nginx)), meine eigenen LaunchAgents müssen manuell in ~/Library/LaunchAgents abgelegt und geladen (launchctl load net.janeden.xxx.plist) werden. Damit die LaunchAgents ihre Arbeit verrichten können, erhalten zsh und python3.9 (/opt/homebrew/bin/python3) Full Disk Access (System Preferences → Security & Privacy Preference Pane → Privacy). In diesem Zusammenhang tritt später der einzige Nachteil der aktiven Paketpflege durch das Homebrew-Projekt zu Tage: Nach jeder Aktualisierung des Python-Paketes muss ich dem Interpreter erneut Zugriffsrechte erteilen. Ein Problem mit brew cleanup entsteht dagegen nur dann, wenn man ungeschickterweise ein Homebrew-Paket per sudo installiert und entsprechend keine Zugriffsrechte auf bestimmte Dateien hat. Die Anpassung der macOS-Standardkonfiguration übernimmt eine modifizierte Fassung des .macOS-Skripts.

Apps

Im dritten Schritt begebe ich mich in das macOS-GUI und installiere die folgenden Apps:

Anders als in den Vorjahren lautet der korrekte Befehl, um meine Schriften in LaTeX nutzen zu können, sudo texhash; updmap -user --enable MixedMap pad.map. TeXLive unterscheidet mittlerweile zwischen systemweiten und nutzerspezifischen Mappings.

Daten

Schließlich muss ~ aus dem Backup rekonstruiert werden. Bei dieser Gelegenheit repariere ich endlich die Fotobibliothek, die seit Jahren nicht vollständig mit der iCloud synchronisiert wird: Ein vollständiger Export und Re-Import aller Bilder bedeutet weniger Arbeit als befürchtet, weil Photos Duplikate beim Import einigermaßen zuverlässig erkennt. Das Verzeichnis ~/Backup wird zum Schluss mit Symlinks zu den wichtigsten Ordnern innerhalb von ~ versehen, ~/Documents/configuration/webstack ergänze ich um Symlinks zu /opt/homebrew/etc/nginx/nginx.conf und /opt/homebrew/etc/uwsgi/apps_enabled/uwsgi.ini.

TTL < 4h.