1201dcbab7
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
77 lines
5.6 KiB
Markdown
77 lines
5.6 KiB
Markdown
# REPORT — userdata arc close-out: FileBrowser umask + Immich/Paperless deploy → controller v0.66.2 + catalog (2026-06-15)
|
|
|
|
Finished the userdata arc: (1) FileBrowser-created folders are now group-writable; (2) Immich deployed
|
|
with its external photo library registered + verified; (3) Paperless deployed and consume verified
|
|
end-to-end. Trunk-based on `main` (controller + app-catalog). Built + deployed + live-verified on demo
|
|
guest 9201 (now 12 GiB RAM).
|
|
|
|
> Validate against pushed source at file:line, not this report.
|
|
|
|
## Confirmed baseline
|
|
- Controller `main` was `d0718e8` = **v0.66.1** → shipped **v0.66.2**.
|
|
- Guest 9201: `pct config` memory **12288** (12 GiB) — confirmed before the deploy phases (was 2 GiB).
|
|
|
|
## Commit hashes
|
|
| Repo | Commit | Scope |
|
|
|---|---|---|
|
|
| controller | `98d5504` | v0.66.2 — FileBrowser umask 002 entrypoint wrapper + test |
|
|
| controller | (this) | docs: README FB umask + REPORT |
|
|
| app-catalog | `67037cc` | paperless OCR lang-pack fix (space-separated `PAPERLESS_OCR_LANGUAGES`) |
|
|
|
|
## Phase 1 — FileBrowser umask (mechanism: ENTRYPOINT WRAPPER, not UMASK env)
|
|
Verified the gtstef/filebrowser:1.3.3-stable image is a single Go binary (`entrypoint ./filebrowser`,
|
|
runs uid 1000) that does **NOT** honor a `UMASK` env — live test: `docker run -e UMASK=002 … umask` →
|
|
`0022`. So `RenderFileBrowserCompose` (`internal/infra/infra.go`) wraps the entrypoint:
|
|
`["sh","-c","umask 002; exec /home/filebrowser/filebrowser"]`. Test asserts the rendered compose carries
|
|
it. **Live proof on 9201** (after deploying v0.66.2 → FileBrowser re-rendered): PID1 `Umask: 0002`; a
|
|
folder created at that umask under the setgid parent → **2775 group 1000**; a uid/gid-1000 app process
|
|
(busybox `--user 1000:1000`) wrote a file INTO that customer folder (664 group 1000) → `APP_WRITE_OK`;
|
|
FileBrowser then deleted it. The pre-fix `Teszt` folder (2755) was the only stale dir — normalized with a
|
|
one-time `find -type d -exec chmod g+rwxs` (no data); no 2755 dirs remain.
|
|
|
|
## Phase 2 — Immich: DEPLOYED + EXTERNAL LIBRARY REGISTERED + verified
|
|
- Deployed via the controller deploy flow (the dashboard's `/api/stacks/immich/deploy` over the public
|
|
URL — mem-gate + USERDATA_PATH + belt all run; NOT a raw compose/CLI shortcut). **Mem-gate PASSED**
|
|
(it refused at 2 GiB; cleared at 12 GiB). All 4 containers **healthy**; memory: server 916 MiB, ML
|
|
231 MiB, postgres 340 MiB, redis 5 MiB (~1.5 GiB total; 8.7 GiB available after).
|
|
- External mount confirmed: `/mnt/felhom-usb/userdata/media/photos → /external/photos (ro)`, 2775 setgid.
|
|
- **External library REGISTERED via the Immich API** (no browser tool in this env — see Note): admin
|
|
account created (creds stored out-of-band), `POST /api/libraries` with `importPaths:["/external/photos"]`.
|
|
- **End-to-end VERIFIED**: a JPEG placed in `media/photos` by a uid-1000 process → `POST /api/libraries/{id}/scan`
|
|
→ `GET …/statistics` returned `{"photos":1,"total":1,"usage":631}`. The photo appears in Immich.
|
|
|
|
## Phase 3 — Paperless: DEPLOYED (UID 1000) + consume verified + catalog OCR bug fixed
|
|
- Deployed via the controller deploy flow; mem-gate passed. Runs as **uid 1000 (USERMAP_UID/GID 1000)**;
|
|
consume mount `/mnt/felhom-usb/userdata/import/paperless → /usr/src/paperless/consume`.
|
|
- **Found + fixed a real catalog bug** (`67037cc`): the default `PAPERLESS_OCR_LANGUAGE=hun+eng` crash-looped
|
|
— the compose fed the `+`-joined value into `PAPERLESS_OCR_LANGUAGES` (the install list, which must be
|
|
space-separated), so the image tried to apt-install a bogus `tesseract-ocr-hun+eng` → `hun` pack missing
|
|
→ Django check crash-loop. Confirmed it's a name bug not network (`tesseract-ocr-hun` installs cleanly).
|
|
Fix: `PAPERLESS_OCR_LANGUAGES=eng hun deu` (fixed space-separated superset). **Verified**: redeployed with
|
|
the default `hun+eng` → boots **healthy**, `tesseract --list-langs` = `deu eng hun`.
|
|
- **Consume VERIFIED end-to-end** (on the final hun+eng deploy): a PDF dropped into `import/paperless` by a
|
|
uid-1000 process → within ~45 s `consume_files_left=0` (paperless **read + deleted** it from the 2775
|
|
shared dir) and `doc_count=1` (ingested/OCR'd). Proves write+delete in the shared dir works.
|
|
|
|
## Phase 4 — close-out
|
|
Controller **v0.66.2 Up (healthy)** on 9201; FileBrowser re-rendered with the umask wrapper; clean logs;
|
|
8.5 GiB free. Full userdata collaboration story now holds with the heavy apps live: customer-created
|
|
folder usable by apps (P1), Immich photos via external library (P2), Paperless consume (P3).
|
|
|
|
## Tests (Linux gate green on 192.168.0.180)
|
|
`internal/infra`: `RenderFileBrowserCompose` emits the umask-002 entrypoint wrapper. Full
|
|
`go build && go vet && go test ./...` green.
|
|
|
|
## Note on the deploy method (transparency)
|
|
The task specified deploying via the dashboard with Claude-in-Chrome, but no browser-automation tool was
|
|
available in this environment. I used the controller's **real deploy endpoint** (the same JSON API the
|
|
dashboard's deploy button calls, over the public URL through traefik/cloudflared) — so the mem-gate,
|
|
USERDATA_PATH injection, and deploy belt all executed; this is NOT a raw `docker compose`/CLI shortcut.
|
|
The Immich external-library registration used the Immich REST API (admin sign-up → login → create library
|
|
→ scan), fully completed and verified, not left as a documented manual step.
|
|
|
|
## Pending / follow-ups (noted, not done)
|
|
- **komga** reports `unhealthy` via its `/api/v1/actuator/health` probe on komga 1.20 despite serving
|
|
(pre-existing healthcheck-definition issue, unrelated to userdata) — fix the healthcheck.
|
|
- Demo admin accounts created for Immich + Paperless to drive verification (creds out-of-band).
|