Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.6 KiB
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
mainwasd0718e8= v0.66.1 → shipped v0.66.2. - Guest 9201:
pct configmemory 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/deployover 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/librarieswithimportPaths:["/external/photos"]. - End-to-end VERIFIED: a JPEG placed in
media/photosby a uid-1000 process →POST /api/libraries/{id}/scan→GET …/statisticsreturned{"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 defaultPAPERLESS_OCR_LANGUAGE=hun+engcrash-looped — the compose fed the+-joined value intoPAPERLESS_OCR_LANGUAGES(the install list, which must be space-separated), so the image tried to apt-install a bogustesseract-ocr-hun+eng→hunpack missing → Django check crash-loop. Confirmed it's a name bug not network (tesseract-ocr-huninstalls cleanly). Fix:PAPERLESS_OCR_LANGUAGES=eng hun deu(fixed space-separated superset). Verified: redeployed with the defaulthun+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/paperlessby a uid-1000 process → within ~45 sconsume_files_left=0(paperless read + deleted it from the 2775 shared dir) anddoc_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
unhealthyvia its/api/v1/actuator/healthprobe 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).