From a154070e03095415e158eea339e29acab7296347 Mon Sep 17 00:00:00 2001 From: Claudio Date: Mon, 18 May 2026 00:12:12 +0200 Subject: [PATCH] LXC 127: capture OIDC bridge, indexer caps, folder fixes, gitea webhook gotcha --- containers/127-mule-photos-new.md | 100 ++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 13 deletions(-) diff --git a/containers/127-mule-photos-new.md b/containers/127-mule-photos-new.md index a7a032a..959559f 100644 --- a/containers/127-mule-photos-new.md +++ b/containers/127-mule-photos-new.md @@ -81,21 +81,22 @@ fallback. ## Why an override exists `docker-compose.photoprism.override.yml` is **only on LXC 127** (not in -the git repo) and pins two M0-era inconsistencies from the upstream -compose file: +the git repo). After the 2026-05-17/18 fixes landed upstream +(commits `cce1d87` for OIDC env names and `3d8e050` for worker caps), +the override has shrunk to just one stanza — the cross-host sidecar +bind: -1. **Sidecar bind address.** Upstream binds `sidecar` to `127.0.0.1:8000` - because the M4 design colocates Caddy with the sidecar. On this test - LXC Caddy lives on a different host (LXC 121), so the override binds - the sidecar port to `0.0.0.0:8000`. -2. **OIDC env-var names.** Upstream passes - `PHOTOPRISM_OIDC_ISSUER_URL` / `_CLIENT_ID` / `_CLIENT_SECRET` / - `_PROVIDER_NAME`, but PhotoPrism actually reads - `PHOTOPRISM_OIDC_URI` / `_CLIENT` / `_SECRET` / `_PROVIDER`. The - override re-maps. Confirmed live with `docker exec pp-app photoprism show config`. +```yaml +services: + sidecar: + ports: !override + - "0.0.0.0:8000:8000" +``` -Both fixes should land upstream on the `new` branch; once they do the -override file becomes dead code and can be removed. +Upstream binds the sidecar to `127.0.0.1:8000` because the M4 design +colocates Caddy with the sidecar. On this test LXC Caddy lives on a +different host (LXC 121), so the port has to be reachable from the +LAN. Delete this file at M4 cutover. ## Auto-deploy @@ -109,6 +110,14 @@ Mirrors the LXC 120 pattern. Push to the `new` branch on [git.hubris.network/dtoro/mule-image](http://git.hubris.network/dtoro/mule-image) → webhook fires → rebuild. The legacy LXC 120 watches `main` and is unaffected. +**Gitea gotcha:** the receiver IP must be in `[webhook] ALLOWED_HOST_LIST` +in `/etc/gitea/app.ini` on [LXC 104](104-gitea.md). LXC 127's +`192.168.8.181` was missing on first bring-up; every push delivered +status 0 with the message `webhook can only call allowed HTTP servers`. +Adding the IP and `systemctl restart gitea` is enough — same list is +also the gating mechanism for the LXC 120 webhook. Verify any future +test instance is added before relying on auto-deploy. + ## Bootstrap secrets Saved on hubris at `/root/mule-photos-new-secrets.txt` (mode 0600): @@ -137,6 +146,71 @@ curl -sk --resolve photos-new.hubris.network:443:192.168.8.175 \ ## Changelog +### 2026-05-18 — OIDC bridge + indexer + folder fixes + +The `new` branch's PhotoPrism stack required several iterations to be +actually usable. Fixes pushed upstream so they apply to anyone running +the M0 compose; the LXC override file shrank to just the cross-host +sidecar port (see [Why an override exists](#why-an-override-exists)). + +**OIDC end-to-end** (upstream commits `4abe6d7`, `9a3ad3e`, `cce1d87`, +plus Caddy `/library/* → /` bounce on LXC 121). + +- The SvelteKit `/login` had a `// OIDC SSO ships in M4` placeholder + but no button. Added a "Sign in with {provider}" button conditional + on `/api/v1/config.ext.oidc.enabled`; click sends the browser to + `/api/v1/oidc/login`. +- The compose file passed OIDC values through `PHOTOPRISM_OIDC_ISSUER_URL` + / `_CLIENT_ID` / `_CLIENT_SECRET` / `_PROVIDER_NAME` — names PhotoPrism + silently ignores. The actual env-var names are `PHOTOPRISM_OIDC_URI` + / `_CLIENT` / `_SECRET` / `_PROVIDER` (see `photoprism show config`). + Renamed upstream; user-facing keys in `.env.photoprism` (OIDC_ISSUER_URL, + OIDC_CLIENT_ID, …) are unchanged. +- PhotoPrism's OIDC callback does **not** set `auth_token` / `auth_session` + cookies. It returns an HTML page that writes the session into + `localStorage` under `pp::session.{id,token,user,provider}` + and then runs `window.location.href = "/library/login"`. Caddy on this + test instance bounces `/library/*` back to `/`, and the SvelteKit root + layout (`bootstrapSessionFromPhotoPrism()`) reads those localStorage + entries on mount, fetches `/api/v1/session/` with the cookied + token, and adopts the session into the SPA store. + +**Indexer caps** (upstream commit `3d8e050`). A fresh index of ~1.2k +photos pushed the LXC load average above 50 with the default +`PHOTOPRISM_INDEX_WORKERS` (NumCPU/2 = 3 here, each forking TF + +ffmpeg + libvips). Compose now reads `PP_WORKERS` / `PP_INDEX_WORKERS` +from `.env.photoprism`, defaulting to 2. Both set explicitly on this +LXC to keep sibling containers happy. + +**Library went RW.** Flipped `PP_READONLY=false` and `PP_ORIGINALS_MODE=rw` +in `.env.photoprism` so the indexer can actually run — `READONLY=true` +disables it entirely. Safe because `/srv/photos-scratch` is the +rsync scratch copy on the LXC rootfs, not the real admin Photos tree. + +**Admin role.** OIDC creates users with `OIDC_ROLE` ONLY on first +registration. The `dtoro` user was created in an earlier flow before +the env-var-name fix, so it landed as `guest` and saw no photos in +the UI. Promoted manually: + +```sql +UPDATE auth_users SET user_role='admin', super_admin=1, can_invite=1 + WHERE user_name='dtoro'; +DELETE FROM auth_sessions WHERE user_name='dtoro'; +``` + +Stale sessions are dropped so a fresh OIDC login mints an admin token. + +**Folder tree** (upstream commits `8083328`, `505fef5`, `cfd85a1`). +PhotoPrism's `path:` operator is exact-match by default but supports +a `*` wildcard. Without it, every internal tree node (year folders, +since photos always nest under YYYY/MM) returned zero hits — both in +the timeline and in the sidecar's folder-count fan-out. Fixed both +to emit `path:"*"`. Also relaxed the root-folder client-side +filter (was clipping to `Path === ''`, which is always empty) so `/` +shows the whole library. Root badge in the sidebar now reads +`config.count.all` directly instead of subtracting Σ(folderCounts) — +the subtraction double-counted after the recursive switch. + ### 2026-05-17 — Bring-up LXC 127 created from `debian-13-standard_13.1-2`, joined to vmbr0 with