Initial documentation of the hubris Proxmox homelab as a cross-linked markdown wiki. Per-node pages, cross-cutting infrastructure pages, an investigation log, and an operations cheatsheet. Each node and topic ends with a Changelog section so changes can be tracked in-place going forward. Refreshed against live state on 2026-04-28 — 14 active LXCs (109 syncthing currently stopped) + 1 VM (108 haos). Reflects post-A/B-test state of the 2026-04-21 hubris crash-loop investigation.
5.2 KiB
120 — mule-images
Hosts mule-image / "mulita" — the photos app at photos.hubris.network. Auto-deploys from dtoro/mule-image on git push origin main.
At a glance
- Hostname:
mule-images - IP:
192.168.8.136 - Privilege: privileged
- Resources: 4 cores / 8 GiB RAM / 60 GiB rootfs
- Mounts:
/mnt/library↔/mnt/library - Public hostname:
photos.hubris.network→ caddy →:3000(frontend)
Stack (/opt/mule-image)
/opt/mule-image IS the working tree of dtoro/mule-image. Compose at /opt/mule-image/docker-compose.yml. Services:
| Service | Port | Notes |
|---|---|---|
| frontend | 3000 | Reverse-proxied by Caddy |
| backend | 8001 | FastAPI |
| worker-vision | — | ML scan worker |
| worker-light | — | Lightweight worker |
| worker-watcher | — | FS watcher |
| db | (pg) | pgvector |
| redis | (rd) | queue |
.env is untracked — git checkout .env will wipe it. Holds:
PHOTO_DIRS=/mnt/library/images/NEXTCLOUD_USERS_HOST_PATH=/mnt/library/homecloudNEXTCLOUD_BASE_URL=https://cloud.hubris.network- OIDC client secret + scopes
SECRET_KEY(generated)
Nextcloud-rooted libraries (since 2026-04-26)
Photo libraries live under each user's Nextcloud files/ tree, NOT in /mnt/library/images/*.
/mnt/library/homecloudis bind-mounted intobackend,worker-light,worker-watcher,worker-visionas/nextcloud-users. Each NC user is/nextcloud-users/<nc_user>/files/.- Reads use that bind directly.
- Mutations (upload, delete, rename, move) dispatch through
services/nextcloud_dav.py(HTTP Basic auth, per-user app password Fernet-encrypted inusers.nextcloud_app_password_enc) so Nextcloud'soc_filecache, trashbin, comments, and desktop-sync clients stay coherent. - Photo copy + cross-system moves return 501 with a "use Nextcloud's web UI" hint — defer until needed.
users.nextcloud_usernameoverrides the default OIDCpreferred_username.dtoro(mule-image) maps toadmin(Nextcloud) — don't assume username equality.- Surviving SourceRoots in DB:
Photos→/nextcloud-users/admin/files/Photos;Memories→/nextcloud-users/admin/files/Memories(both owned bydtoro). Usermulihasnextcloud_username=mulibackfilled but no SourceRoot yet. - Pre-migration DB dump:
/root/snapshots/mulita-pre-nc-migration-20260426-075132.dump(11 MB) on the host.
Authentication (since 2026-04-22)
Native OIDC via Authentik. Code in backend/app/auth_oidc.py, routes /api/v1/auth/oidc/{login,callback}. Authentik side:
- OAuth2/OIDC Provider, client ID
fCuHew48ONTskDjUKnMTZjFbVXuHwvQqTScQRNQ1 - App slug
mule-image - Redirect URI:
https://photos.hubris.network/api/v1/auth/oidc/callback
Backend container needs extra_hosts: auth.hubris.network:192.168.8.175 via docker-compose.override.yml (gitignored). Otherwise Authlib's metadata fetch fails with SSL: CERTIFICATE_VERIFY_FAILED: self-signed certificate (it ends up at a random public host because LXC DNS resolves the public IONOS A record).
Caddyfile stays plain reverse_proxy 192.168.8.136:3000 — no forward-auth, no /api/* bypass needed.
Auto-deploy
Push to dtoro/mule-image main → gitea webhook → http://192.168.8.136:9797/deploy → mule-deploy-webhook.service:
- Validates HMAC against
/etc/mule-deploy/secret - Filters to
refs/heads/main - Runs
/opt/mule-deploy/deploy.shin a daemon thread (returns 202 immediately — docker builds exceed gitea's request timeout) git pull --ff-only+docker compose up -d --build+docker image prune -f
Deploy tooling is outside the app repo: /opt/mule-deploy/{deploy.sh,webhook.py}, secret at /etc/mule-deploy/secret, unit at /etc/systemd/system/mule-deploy-webhook.service. Same shape as the Caddy + Artifacto pipelines. Gitea webhook id 6.
app.ini ALLOWED_HOST_LIST on gitea includes 192.168.8.136.
Logs: pct exec 120 -- journalctl -u mule-deploy-webhook -f.
Manual deploy: pct exec 120 -- /opt/mule-deploy/deploy.sh.
For pushes from inside the LXC, gitea creds at /etc/mule-deploy/git-credentials (mode 600) — same token as /etc/caddy-deploy/git-credentials on caddy.
Related
- Nextcloud (114) — source of truth for photo libraries
- Authentik (124)
- Caddy (121)
- DNS
- Auto-deploy
- Gitea (104)
Changelog
2026-04-28 — wiki entry created
Initial documentation.
2026-04-26 — Nextcloud-rooted libraries shipped
Bind /mnt/library/homecloud into the workers, reads via filesystem, writes via WebDAV. users.nextcloud_username override field added; dtoro → admin mapping. Surviving SourceRoots cleaned up to NC paths.
2026-04-22 — native OIDC via Authentik
Authlib-based code in backend/app/auth_oidc.py. extra_hosts override for auth.hubris.network in compose override (gitignored).
2026-04-21 — auto-deploy pipeline shipped
Webhook receiver at :9797, async deploy returning 202. Mirrors caddy-conf / gitea-customizations.