- docker-compose.yml: a `languagetool` service (erikvl87/languagetool:6.8),
internal only, 1 GB heap, one CPU, a 28 GB memory limit that is room for the
n-gram page cache (reclaimable, not memory in use), and a low-priority
warm-up read of the n-gram files at start so first checks hit RAM even on
mechanical disks. `init` creates $DATA_ROOT/languagetool-ngrams; the app
containers get LANGUAGETOOL_URL (empty turns the check off).
- `webmail.sh ngrams [langs]` (default en de fr es): deploy/ngrams.py, run in
the backend image, downloads LanguageTool's n-gram data with resume, checks
free space first (unpacked is ~2x the zip: ~26 GB for all four), unpacks into
a temp folder and moves it into place, then recreates the engine to load it.
languagetool.org refuses Python's default User-Agent, so it sends its own.
- `doctor` reports whether the spell checker answers and which n-gram
languages are installed.
- docs/nas-install.md and .env.prod.example describe all of it.
Verified locally: German n-grams (1.58 GB -> 3.06 GB) load, and catch what the
rules alone do not ("liegt ihm Schrank" -> im, "Der Patenten" -> Patienten).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>