Datenverlust behoben: - Nach hartem Stopp blieb das Original in working/ liegen und wurde nie wieder angefasst (_scan_existing sah nur incoming/). Es wird jetzt beim Start an Ort und Stelle wieder aufgegriffen, mit Kollisionsschutz gegen gleichnamige neue Scans; angefangene __ocr_-Fragmente werden geloescht. - TimeoutStopSec 30 -> 300, damit laufendes OCR zu Ende laufen darf. Config-Drift sichtbar gemacht: - Neues --check-config (Exit 0 sauber / 1 Warnungen / 2 Fehler), das update.sh vor dem Neustart ueber alle Instanz-Configs laufen laesst. - Warnungen fuer [ocr].timeout >= 900 (seit 0.4.0 pro SEITE) und gesetztes pdfa_level, beim Dienststart wie im Check. - Unbekannte Config-Keys werden nicht mehr still verworfen, sondern genannt. Updater feldtauglich: - venv-Health-Check erkennt toten Symlink UND Versions-Drift gegen das System-Python; --rebuild-venv als ausdruecklicher Weg nach einem Debian- Major-Upgrade. Neubau ist ganz-oder-gar-nicht mit Rollback. - apt-Pakete werden auch beim Update synchronisiert (Quelle: install.sh). - Instanz-Erfassung inkl. activating/failed, Verifikation prueft is-failed und NRestarts statt sleep 1 + is-active. - Backup enthaelt Configs, Unit, Drop-ins und pip-freeze.txt, liegt auf 0600 und rotiert auf 5; schlaegt es fehl, bricht das Update vorher ab. - ERR-Trap faehrt die vorher laufenden Instanzen wieder hoch. - lxc-compat.conf wird beim Update nachgezogen. - requirements.txt gepinnt (ocrmypdf 16.13.0, geprueft fuer Python 3.11+3.13). Doku in Installation / Update / OS-Upgrade aufgeteilt (docs/). 135 Tests gruen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6.8 KiB
Debian-Major-Upgrade
Wie der Hotfolder ein Distributions-Upgrade übersteht (12 → 13, später 13 → 14).
Verwandte Dokumente: README · Installation · Update
Warum das ein eigener Ablauf ist
Die venv unter /opt/pdf-ocr-hotfolder/venv/ hängt an der Python-Version der
Distribution. Ein apt full-upgrade von Debian 12 auf 13 tauscht Python 3.11
gegen 3.13 aus. Danach zeigt venv/bin/python auf einen Interpreter, den es so
nicht mehr gibt — systemd quittiert den Start jeder Instanz mit 203/EXEC, und
auch wenn der Interpreter noch existiert, passen die installierten Pakete nicht
mehr zum System-Python.
Die venv muss nach dem Sprung neu gebaut werden. Ein normales
sudo ./update.sh genügt dafür nicht sicher genug — es gibt den ausdrücklichen
Schalter --rebuild-venv.
Der Ablauf
1. Vorher updaten
cd /pfad/zum/repo
git pull
sudo ./update.sh
Das bringt die Installation auf den aktuellen Stand und erzeugt vor allem ein
frisches Backup inklusive pip-freeze.txt — die Liste der Paketversionen,
die auf dem alten System liefen. Inhalt und Ort des Backups:
UPDATE.md.
2. Instanzen stoppen
sudo systemctl stop 'pdf-ocr-hotfolder@*'
Während des Upgrades darf kein OCR laufen: Ghostscript, Tesseract und die Python-Pakete werden mitten im Betrieb ausgetauscht.
Geduld. Die Unit hat
TimeoutStopSec=300, damit ein laufendes OCR sauber zu Ende kommt. Ein Stop kann pro Instanz bis zu 5 Minuten dauern — bei mehreren Instanzen entsprechend länger. Nicht mitkill -9nachhelfen; ein harter Stopp lässt das Original inworking/liegen (der Dienst nimmt es beim nächsten Start zwar wieder auf, aber der Durchlauf ist verloren).
Prüfen, dass wirklich alles steht:
systemctl status 'pdf-ocr-hotfolder@*'
3. Distribution upgraden
Der übliche Debian-Weg — Sources auf das neue Release umstellen, dann:
sudo apt update
sudo apt full-upgrade
sudo reboot
Die Instanzen sind enabled und starten nach dem Reboot mit; mit der alten venv
scheitern sie (203/EXEC). Das ist erwartet und wird im nächsten Schritt
behoben.
4. venv neu bauen
cd /pfad/zum/repo
git pull
sudo ./update.sh --rebuild-venv
--rebuild-venv erzwingt den Neubau. Der Rest des Updates läuft wie gewohnt
(siehe UPDATE.md) — die
System-Pakete werden dabei ebenfalls abgeglichen, auch python3-venv für das
neue Python.
Der Neubau ist ganz oder gar nicht:
- Die alte venv wird nach
venv.old-<timestamp>verschoben. python3 -m venvbaut neu.- Die Requirements werden installiert.
- Erst bei Erfolg wird die alte venv gelöscht.
5. Wenn ein Pin nicht mehr passt
Scheitert pip install an einer gepinnten Version, bricht das Skript ab und
sagt genau, was los ist:
- die letzten 25 Zeilen der pip-Ausgabe,
- das gescheiterte Paket ("Gescheitertes Paket: …"),
- die Diagnose: "eine in requirements.txt fest gepinnte Version gibt es für Python <version> nicht (mehr)",
- den nächsten Schritt: requirements.txt anheben und
update.sh --rebuild-venverneut laufen lassen.
Die alte venv ist dann zurückgerollt — es liegt keine halb gefüllte venv herum. Sie hängt zwar weiterhin am alten Interpreter und die Instanzen laufen damit nicht (das sagt das Skript auch), aber der Zustand ist eindeutig.
Also:
# im Repo, auf einer Testmaschine
vim requirements.txt # Version des genannten Pakets anheben
pytest # Suite muss grün bleiben
git commit -am 'requirements: <paket> auf <version> anheben'
git push
# auf dem Zielsystem
git pull
sudo ./update.sh --rebuild-venv
6. --rebuild-venv vergessen?
Halb so wild: update.sh prüft die venv auch ohne den Schalter und baut sie bei
Versions-Drift von selbst neu. Geprüft wird
- ob das Verzeichnis und
venv/bin/pythonüberhaupt existieren, - ob der Interpreter der venv noch läuft (toter Symlink nach dem Upgrade),
- ob seine
major.minorzum System-python3passt, - ob
pyvenv.cfgdieselbe Version nennt wie der Interpreter.
Stimmt eines davon nicht, nennt das Skript den Grund und baut neu.
--rebuild-venv ist also nicht der einzige, aber der ausdrückliche Weg —
und der, den man nach einem Distributions-Upgrade nimmt, statt sich auf die
Erkennung zu verlassen.
Danach prüfen
Laufen alle Instanzen?
systemctl status 'pdf-ocr-hotfolder@*'
update.sh hat das schon verifiziert (Wartezeit, is-failed, Crash-Loop) und
in der Zusammenfassung Soll gegen Ist gestellt — ein Exit 0 heißt, dass jede
Instanz, die vorher lief, auch wieder läuft.
Sind die Configs sauber?
for f in /etc/pdf-ocr-hotfolder/*.toml; do
sudo /opt/pdf-ocr-hotfolder/venv/bin/python -m pdf_ocr_hotfolder \
--check-config --config "$f"
done
Exit 0/1/2 und was bei Warnungen zu tun ist: UPDATE.md.
Läuft eine echte PDF durch?
cp test.pdf /var/lib/pdf-ocr-hotfolder/<instanz>/incoming/
journalctl -u pdf-ocr-hotfolder@<instanz> -f
Im outgoing/ muss das OCR-PDF liegen, im Journal steht OCR done. Das ist der
einzige Test, der die neue venv und die neuen System-Binaries (Tesseract,
Ghostscript) wirklich anfasst — systemctl status sagt darüber nichts.
Ghostscript-Version auf dem neuen Release ansehen:
gs --version
Auf Debian 13 ist der Ghostscript-Bug aus Debian 12 kein Thema mehr; ein
bookworm-backports-Eintrag unter /etc/apt/sources.list.d/ gehört nach dem
Upgrade entfernt. Hintergrund:
INSTALLATION.md.
Pins in requirements.txt
Die Python-Abhängigkeiten sind bewusst fest gepinnt:
ocrmypdf==16.13.0
watchdog==6.0.0
requests==2.33.1
paramiko==4.0.0
Ohne Pins würde ein pip install --upgrade bei jedem Update ungefragt eine neue
Major-Version ziehen — ein Sprung von ocrmypdf 16 auf 17 reißt sonst alle
Instanzen auf einmal, und zwar im Moment des Updates, nicht zu einem Zeitpunkt,
den man sich ausgesucht hat.
Die aktuellen Pins sind gegen Python 3.11 (Debian 12) und 3.13 (Debian 13) geprüft; für beide gibt es fertige Wheels, es wird nichts kompiliert.
Beim Anheben:
- Testmaschine benutzen — nie direkt auf dem produktiven Hotfolder.
- Dort
update.sh --rebuild-venvfahren, damit die Pakete wirklich frisch aufgelöst werden. pytestmuss grün bleiben (135 Tests).- Eine echte PDF durchschieben — die Test-Suite mockt ocrmypdf, ein Major-Sprung fällt dort also nicht auf.
- Erst dann committen und auf die produktiven Systeme geben.
Der ocrmypdf-Sprung 16 → 17 ist ein Major-Sprung und gehört in einen eigenen Vorgang mit eigenem Test, nicht in ein OS-Upgrade.