diff --git a/operator-token-runbook.md b/operator-token-runbook.md index cf29527..6fabfc1 100644 --- a/operator-token-runbook.md +++ b/operator-token-runbook.md @@ -39,6 +39,25 @@ copy, the portal's Cloudron calls start returning `401` — which breaks provisioning (new members can't be created) and the member dashboard (its usage/keys data is resolved through the portal's Cloudron calls). +## Chat image: spaCy model for document parsing (EPUB/DOCX) + +Open WebUI's document parser (`unstructured`) lazily downloads the spaCy model +`en_core_web_sm` on first EPUB/DOCX parse — but the app directory is read-only +under Cloudron, so that install always fails ("Errno 30 Read-only file +system"). Fixed 2026-10-14 (issue #20) by pre-installing the model into +persistent storage: + +- `/app/data/spacy_model/` holds the unpacked wheel + (SHA-verified `en_core_web_sm-3.8.0-py3-none-any.whl` from the pinned URL in + `unstructured/nlp/tokenize.py`). +- App env has `PYTHONPATH=/app/data/spacy_model` so `import en_core_web_sm` + resolves and the lazy download never triggers. + +**Restore caveat:** a backup restore from before 2026-10-14 will NOT contain +the model dir — re-create it (download the pinned wheel, unzip into +`/app/data/spacy_model/`, verify `spacy.load("en_core_web_sm")` works in the +container). The `PYTHONPATH` env survives restores (it's in app config). + ## Scheduled tasks (scheduler addon) The portal and gateway run their own housekeeping via the Cloudron scheduler