LXC 127: capture OIDC bridge, indexer caps, folder fixes, gitea webhook gotcha
This commit is contained in:
@@ -81,21 +81,22 @@ fallback.
|
|||||||
## Why an override exists
|
## Why an override exists
|
||||||
|
|
||||||
`docker-compose.photoprism.override.yml` is **only on LXC 127** (not in
|
`docker-compose.photoprism.override.yml` is **only on LXC 127** (not in
|
||||||
the git repo) and pins two M0-era inconsistencies from the upstream
|
the git repo). After the 2026-05-17/18 fixes landed upstream
|
||||||
compose file:
|
(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`
|
```yaml
|
||||||
because the M4 design colocates Caddy with the sidecar. On this test
|
services:
|
||||||
LXC Caddy lives on a different host (LXC 121), so the override binds
|
sidecar:
|
||||||
the sidecar port to `0.0.0.0:8000`.
|
ports: !override
|
||||||
2. **OIDC env-var names.** Upstream passes
|
- "0.0.0.0:8000:8000"
|
||||||
`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`.
|
|
||||||
|
|
||||||
Both fixes should land upstream on the `new` branch; once they do the
|
Upstream binds the sidecar to `127.0.0.1:8000` because the M4 design
|
||||||
override file becomes dead code and can be removed.
|
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
|
## 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.
|
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
|
## Bootstrap secrets
|
||||||
|
|
||||||
Saved on hubris at `/root/mule-photos-new-secrets.txt` (mode 0600):
|
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
|
## 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:<storageNamespace>: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/<id>` 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:"<folder>*"`. 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
|
### 2026-05-17 — Bring-up
|
||||||
|
|
||||||
LXC 127 created from `debian-13-standard_13.1-2`, joined to vmbr0 with
|
LXC 127 created from `debian-13-standard_13.1-2`, joined to vmbr0 with
|
||||||
|
|||||||
Reference in New Issue
Block a user