Commit Graph

70 Commits

Author SHA1 Message Date
b6c9184a7b decommission: destroy plato (LXC 126)
LXC 126 stopped and destroyed on hubris. Remove all live references:
inventory, container doc, host file, README, containers index, auto-deploy
pipeline, DNS entry, SSH access table, nfs-export mount list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 22:32:59 +02:00
cb0c1a5c0d house: add Google Calendar OAuth config to docs 2026-06-27 14:40:29 +02:00
ddf541ebd3 house: switch Paperless to native DMS connector (remove WebDAV bridge) 2026-06-26 19:57:50 +02:00
4472e73ae1 Yuvomi deployment: LXC 129 house.hubris.network, Docker, Caddy, DNS, VPS traefik, Authentik OIDC, Paperless WebDAV bridge 2026-06-26 19:06:49 +02:00
41f22c2d85 trmnl (128): auto-deploy pipeline + LAN DNS record wired
- auto-deploy.md: dtoro/terminalito pipeline (webhook 12, :9797), ALLOWED_HOST_LIST
  += 192.168.8.211, changelog
- 128-trmnl.md: auto-deploy now wired, Technitium A record done, changelog
- 107-dns.md: A record trmnl -> 192.168.8.175 (changelog)
- 104-gitea.md: webhook id 12 + allowed host (changelog)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:06:56 +02:00
b7cfc350b3 trmnl (128): public path verified live; root-cause the mesh outage
Root cause of the provision-time 504s: netbird home-lab-network (192.168.8.0/24)
had no active routing peer — mac-mini routing peer's netbird daemon was down, so
all home-backed public services (artifacto/blog/trmnl) 504'd at the VPS edge.
netbird up on mac-mini restored it; verified trmnl public 200/401, artifacto 200.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 17:38:57 +02:00
fffa5560eb trmnl (128): provisioned — container page, inventory, ingress
LXC 128 trmnl hosts the TRMNL plugins middleware (dtoro/terminalito), polled by
TRMNL cloud. trmnl-plugins.service on :9851; Caddy block + LE cert; VPS traefik
router trmnl-public + cert mirror. Public path pending VPS<->home netbird route
recovery (was "No networks available" at provision time, artifacto/blog 504 too).
LAN Technitium record + SOPS enrollment + Google/MVG creds pending. Plan -> In Progress.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 17:24:31 +02:00
4c83960035 docs: sab.hubris.network Authentik auth — update arriman + caddy pages 2026-06-13 11:58:21 +02:00
ddc5e8771a docs: Authentik session lifetime investigation, fix docs, changelog 2026-06-06 23:45:59 +02:00
6d808a1fd8 arriman: SABnzbd HTTPS enabled on port 9090 2026-06-05 00:21:56 +02:00
6b5fed040f arriman: all services behind gluetun, SAB port 8082 fix 2026-06-05 00:14:06 +02:00
2f81287eb1 cleanup: destroy LXC 124, remove stale docs, update DNS refs to Technitium 2026-06-04 23:12:06 +02:00
e32b21072d claudio-bot: decommission LXC 123, archive repos, migrate monitoring to Hermes
- Destroy LXC 123 (claudio-bot) — freed 8 GiB rootfs, 512 MiB RAM, 1 core
- Archive dtoro/claudio-bot and dtoro/claudio-monitor on Gitea (read-only)
- Stop claudio-monitor.timer on hubris, remove /opt/claudio-monitor
- Extend homelab-hardware-health skill with LXC resources, service health, apt/docker drift
- Create homelab-health-watchdog cron (15 min, Matrix alerts, actionable options)
- Wire Matrix (matrix:dtoro) as health alert delivery platform
- Update 13 files: inventory, containers/*, infrastructure/*, hosts/*, README, .sops.yaml
- Add deprecation plan at plans/2026-06-04_130000-deprecate-claudio-bot.md
2026-06-04 10:14:56 +02:00
edac189aa7 docs: DHCP pool narrowed to .241-.254; ZimaOS IP drift documented
- network.md: updated pool range, fixed 'below .100' claim, added changelog
- 107-dns.md: updated pool range, fixed 'below .100' claim, added changelog
- 100-zimaos.md: documented IP drift (.195→.103) and Caddy 502
- plan: .hermes/plans/2026-06-03_223218-dhcp-pool-exclude-static-ips.md

DHCP scope changed via Technitium API. No static IPs changed. Old leases
(.101-.110) expire naturally by 2026-06-04.
2026-06-03 22:50:33 +02:00
cb1d8b39b9 Merge branch 'main' of git-ssh.hubris.network:dtoro/Homelab-Docs
# Conflicts:
#	.sops.yaml
#	containers/107-dns.md
#	infrastructure/dns.md
2026-06-03 22:02:52 +02:00
f81310ae6b dns: Technitium-master sync to NetBird managed zone + cleanup
- scripts/dns-sync.py: reconcile Technitium named A-records -> NetBird managed
  zone via API (cron */10 on dns LXC 107). Single authoring source; kills the
  manual drift behind the auth/sso/nfs-export saga.
- secrets/netbird-pat.yaml: sops-encrypted NetBird API PAT for the sync.
- dns.md / 107-dns.md: document the sync model + why forward-to-Technitium was
  abandoned (NetBird self-IP / nameserver-group quirks).
- Cleanup: removed inert Mac secondary; reverted primary AXFR; home-lab-dns ->
  [192.168.8.2] (1/1 Available); deleted vestigial Proxmox Names group.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 21:59:54 +02:00
ce1bf4d0d2 docs: gluetun VPN + static IP migration (2026-06-02) 2026-06-02 22:42:46 +02:00
41de395240 docs: post-migration changelog entries on hubris, caddy, dns
hosts/hubris.md:
- Update At a glance network section: vmbr1 uplink (192.168.178.10),
  vmbr0 portless internal bridge with 192.168.8.1 alias
- Remove Phase 1 WiFi failover section (wlp3s0 disabled 2026-06-02)
- Changelog: Slate AX retired, SODOLA added, Proxmox as subnet router

containers/121-caddy.md:
- Changelog: caddy.service unit was missing from hubris1 package,
  recreated manually; risk of loss on package reinstall noted

containers/107-dns.md:
- Update Who points here: Technitium DHCP hands out .2 as DNS for
  homelab clients; Fritz!Box LAN clients still get Fritz!Box DNS
- Add DHCP section documenting the homelab scope (100-240, gw .1)
- Changelog: DHCP enabled 2026-06-02, replaces Slate AX DHCP

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 22:02:34 +02:00
ec48041b54 fix: correct endpoint path to /mcp for streamable-http transport 2026-06-02 00:25:34 +02:00
00a891b154 ssh: fix LXC name parsing in deploy-keys.sh (Lock column edge case) 2026-06-02 00:06:58 +02:00
563dbe21b1 arch-migration P2: Technitium dns LXC (107); retire LXC 124
- containers/107-dns.md: new Technitium DNS server page
- dns.md: dnsmasq -> Technitium changelog; flags 3 overlapping DNS sources + router DHCP action
- 124-authentik: marked RETIRED (shut down)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 22:10:18 +02:00
4b713d7805 arch-migration P1: document sso.hubris.network outpost callback domain
Domain-level forward-auth needs its own external_host domain when the IdP core
and outpost are on different hosts. sso.hubris.network -> Caddy -> LAN outpost.
Includes the redirect_uris-regeneration gotcha. Carry the DNS record into
Technitium in DNS Phase 2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 00:45:25 +02:00
2762dcbdb8 arch-migration P1: dedicated forward-auth outpost (LXC 106)
- containers/106-auth-outpost.md: new LAN outpost page
- 124-authentik: forward-auth cut over, Authentik stopped (DNS-only now)
- investigation: forward-auth outpost marked RESOLVED

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 00:33:26 +02:00
8dbba323c1 authentik: migrate from LXC 124 to VPS; eliminate mesh bootstrap deadlock
Moved Authentik (2026.2.2 -> 2026.5.2, +Redis, dedicated auth Docker net)
off LXC 124 onto the VPS so netbird-mgmt's OIDC dependency no longer requires
the mesh it authenticates. depends_on: service_healthy makes the deadlock
structurally impossible. Full Postgres DB migrated (users/apps/passwords/groups).

- investigations/2026-05-31-authentik-vps-migration.md: full writeup + lessons
- 124-authentik: migration banner + changelog (now legacy; dnsmasq stays)
- dns: auth.hubris.network -> 82.165.190.79; NetBird resolver cache gotcha
- ingress: auth served by local container via Docker-provider labels (not cert-mirror)
- mesh: follow-up entry superseding the morning band-aid; bootstrap note obsolete

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 23:17:00 +02:00
b34d362c19 photos: mule-image cutover to PhotoPrism stack on 120, retire 127
Mulimage 2.0 merge (dtoro/mule-image 70dc1b6) replaces the legacy
FastAPI/Celery/Postgres stack with PhotoPrism + Go sidecar + MariaDB +
SvelteKit. LXC 120 now runs that architecture in production; LXC 127
(the M0 evaluation host) was destroyed in the same session.

- inventory.yaml: drop mule-photos-new host + photos_new service.
- containers/index.md: bump 120's row (6 cores / 12 GiB / iGPU
  passthrough), move 127 to Recently-destroyed.
- containers/120-mule-images.md: rewrite stack + library-access +
  auth sections; add 2026-05-22 cutover changelog entry.
- containers/127-mule-photos-new.md: add closing changelog entry and
  decommission banner; rest left intact as archaeology.
- hosts/mule-photos-new.yaml: removed (regenerated from inventory.yaml).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 00:53:34 +02:00
d41d73f323 device-code onboarding: bootstrap auto-installs deps + netbird; Authentik device flow wired
Two changes that together collapse new-workstation onboarding from ~7 steps
to ~2 commands:

* bootstrap.sh:
  - Dep-check now AUTO-INSTALLS missing tools (apt/dnf/brew) instead of
    printing instructions and exiting. Re-verifies after install.
  - New pre-mesh-check block: if netbird isn't installed, installs it
    from the netbird apt/dnf repo (or `brew install --cask netbird` on
    Darwin), then if mgmt isn't connected, runs `netbird up
    --management-url=https://netbird.hubris.network --ssh-jwt-cache-ttl 86400`.
    Operator clicks the device-code URL inline. Waits up to ~30s for
    Management: Connected before continuing. Skipped on --no-secrets +
    --dry-run.

* containers/124-authentik.md: replaces the "KNOWN MISSING — Device Code
  Stage" subsection with a working recipe — Authentik 2026.2 routes
  /device via a BRAND-level "Device code flow" field, not a provider
  field. Documented stage bindings for a `default-device-code-flow`
  flow (identification → password → user-login → consent) and the
  brand-level binding step.

* operations/agent-enrollment.md: Path B (interactive `netbird up`) is
  now the default; Path A (setup-key) demoted to "headless/scripted"
  alternative. "Install dependencies" section collapsed into a note
  that bootstrap handles it, with the manual recipes kept in a
  collapsible <details> block for air-gapped use.

The flow uniquely available to lab owners (single Authentik user today)
still relies on the first-time-owner sqlite promotion documented in
124-authentik.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 15:05:27 +02:00
b42a986cc0 wiki: document 2026-05-21 netbird vanilla migration
Updates to four pages reflecting the combined → vanilla mgmt+signal+relay+coturn
cutover and the IONOS-3478-firewall-exception discovery:

* infrastructure/mesh.md — rewrites the ICE/STUN section to cover the new
  TURN endpoint, the IONOS upstream TCP-3478 filtering (load-bearing,
  undocumented before today), and the verification probe. New changelog
  entry covering the migration outcome + Device Code Stage gap.

* infrastructure/vps-hardening.md — "At a glance" lists the new 6-service
  docker stack + host coturn. Firewall section notes the new
  `iifname ens6 tcp dport 3478 accept` rule plus the IONOS upstream
  exception. New changelog entry.

* containers/124-authentik.md — replaces the "Netbird IdP integration —
  DEFERRED" section with the LANDED state: Provider details (Public
  client type — Confidential breaks PKCE on the dashboard SPA), the
  first-time owner-promotion sqlite recipe, the missing Device Code
  Stage gap + workaround (setup-keys), and a note that the old 2026-04-22
  pre-work Provider/App is now obsolete and safe to delete. Updated
  changelog (Phase 6 landed).

* operations/agent-enrollment.md — new "Getting onto Netbird" subsection
  explaining the setup-key path (currently the only working flow until
  Device Code Stage lands) and why direct OIDC from the public internet
  fails (auth.hubris.network is mesh-only-reachable). Prerequisites table
  row updated to point at the new section.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 13:48:01 +02:00
root
e8c2ccf7bb wiki: document homelab-context distribution system
Adds infrastructure/homelab-context.md as the architecture reference for
the cross-client context + MCP + secrets-issuance system. Updates:

- 105-apps.md: two new ## Stacks sections (homelab-mcp, secrets-issuance)
  with their deploy pipelines + a row each in the public-hostname table;
  changelog entry.
- auto-deploy.md: both new pipelines added to the table (one repo, two
  webhooks, same push); per-pipeline notes covering the clone-per-service
  pattern and the deploy.sh self-restart caveat; changelog entry.
- README.md: link to the new infrastructure page.

Operational walkthrough already lives at operations/agent-enrollment.md;
this commit is the architecture side of the same story.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 18:34:45 +02:00
Claudio
8f598a0e7a 127-mule-photos-new: deploy.sh fix for OIDC state-cookie rotation
PhotoPrism rotates its session HMAC key on every container start, so any
auto-deploy that recreated pp-app invalidated in-flight OIDC logins. The
deploy script was force-recreating + image-pulling on each push; pinned
both so pp-app survives a routine code deploy.
2026-05-18 21:36:29 +02:00
root
bb063d6f94 127-mule-photos-new: pre-transcode pass + perf characterisation
Measured cold-cache behaviour: thumbnails ~2ms, HEVC video playback
12-21s TTFB because libx264 transcodes inline and serialised one
ffmpeg at a time. Sibling thumbs unaffected (~2ms during transcode).
With 11/45 .mov files already pre-baked, ~75% of clicks were cold.
Ran `photoprism convert` to bring sidecar coverage to 45/45; previously
cold videos now serve in ~2ms TTFB.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 10:12:14 +02:00
Claudio
a154070e03 LXC 127: capture OIDC bridge, indexer caps, folder fixes, gitea webhook gotcha 2026-05-18 00:12:12 +02:00
Claudio
eaa014d37a Add LXC 127 mule-photos-new (PhotoPrism M0 test on @new branch) 2026-05-17 21:52:31 +02:00
Claudio
5dda267013 118-elementsynapse: install suppress_redactions push-rule for @admin
Stops redaction events (Signal disappearing messages, deletes,
etc.) from bumping the mobile notification badge in the
future.
2026-05-15 21:59:37 +02:00
Claudio
565453773c 118-elementsynapse: phantom-notification cleanup + DB fact-fix
Synapse runs on SQLite (not Postgres — Postgres only hosts the
mautrix bridge dbs). Documented the post-disk-full
event_push_actions cleanup that took @admin'\''s phantom count
from 125 to 4.
2026-05-15 21:56:35 +02:00
Claudio
c9eb7fdab3 118-elementsynapse: document disk-full fix + bridges
Rootfs grew to 16 GiB on 2026-05-15. Added bridges section
(mautrix slack/signal/meta/linkedin/whatsapp), synapse-admin
port, Postgres backend note, and operational tips for future
disk growth.
2026-05-15 21:48:58 +02:00
Claudio
685d6a9d48 Decommission LXC 109 (syncthing)
Container had been stopped since 2026-04-21 and was never re-enabled.
pct destroy 109 --purge cleaned up vm-109-disk-0 on local-lvm and the
config file. /mnt/library/syncthing subtree was already empty at the
time of destruction and is retained as an empty dir (no real data to
migrate or back up).

- README.md, containers/index.md: removed row, moved to "recently
  destroyed" table
- hosts/hubris.md: dropped from /mnt/library subtree list, updated
  containers/index summary line, added changelog entry
- infrastructure/media-permissions.md: dropped from membership table
  and onboarding example, generalised pct-exec gotcha hostname,
  added changelog
- vms/100-zimaos.md: dropped from "existing fleet" enumeration
- containers/102-nfs-export.md: dropped from bind-mount sibling list
  (7 LXCs now, not 8)
- containers/109-syncthing.md: deleted

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 23:12:32 +02:00
Claudio
82d4e35fcb Promote NFS export to rw + capture ZimaOS Drives-API finding + mesh reachability
After Files-UI evaluation passed (library renders as folder, thumbnails
work), flipped /etc/exports from ro to rw on LXC 102. Tested: write from
ZimaOS appears on /mnt/library as www-data:media, confirming the
all_squash,anonuid=33,anongid=10000 design works.

Documented two architectural findings discovered this session:
- ZimaOS Drives panel sources from GET /v2/local_storage/storages (read-only
  API). Network shares cannot become Drives — Files-as-folder is supported.
- Mesh peers reach ZimaOS via hubris's existing 192.168.8.0/24 netbird subnet
  advertisement; no new infra needed, just DNS (Management nameserver group
  for hubris.network or per-device /etc/hosts override).
2026-05-14 22:29:11 +02:00
root
060eff826c Decommission LXC 116 (heaper)
User destroyed the heaper LXC on 2026-05-14. Removed it from the
container index, README quicktable, hubris host doc, and
media-permissions membership table; moved to the "recently destroyed"
archaeology list. /mnt/library/heaper retained (224 MiB).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:55:53 +02:00
claudio
838052543b 120-mule-images: drop AI pipeline, swap to plain postgres, log refresh
Reflects state after the 2026-05-14 session: the OpenCLIP vision
classifier and worker-vision are gone, the db image is now postgres:16,
and the one-shot full_refresh.py reaped 7982 orphan thumbnail dirs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 01:02:48 +02:00
Claudio
23c7f6a4f1 Document TCP BBR + Apache keepalive tuning (Nextcloud throughput follow-up) 2026-05-13 21:22:17 +02:00
Claudio
c27cd99c6d Document Nextcloud throughput tuning (FPM + event MPM + opcache JIT + MariaDB) 2026-05-13 21:01:32 +02:00
claudio
94d02785f6 wiki: plato auto-deploy (gitea webhook on dtoro/Plato → LXC 126:9799)
- infrastructure/auto-deploy.md: Plato pipeline added (Shape B,
  port 9799, hook id 8); ALLOWED_HOST_LIST gains 192.168.8.190;
  per-pipeline note for the LXC 126 specifics (origin URL, no
  ProtectHome); Changelog updated
- containers/126-plato.md: Auto-deploy section + Changelog entry
2026-05-13 09:00:34 +02:00
claudio
40691dae20 wiki: add 126-plato, decommission 125-seafile
- containers/126-plato.md: Plato (notes/discovery) on LXC 126 — stack,
  bind mount, caddy + DNS, fresh-DB bootstrap workaround
- containers/125-seafile.md: removed (LXC destroyed 2026-05-13)
- containers/index.md: 126 added; 125 moved to recently-destroyed
- infrastructure/dns.md: plato entry added, files entry removed,
  Changelog reflects both
- README.md: top-level quick-links table swaps 125 → 126
2026-05-13 08:52:55 +02:00
Claudio on hubris
1ad56435e5 seafile: enable Metadata management + Views (Pro)
ENABLE_METADATA_MANAGEMENT=True + METADATA_SERVER_URL=http://seafile-md-server:8084 in seahub_settings.py. Library owners can now toggle metadata per library and create table/gallery/kanban Views over their files.
2026-05-12 19:25:14 +02:00
Claudio on hubris
dc0780bcaf seafile: add Pro metadata-server + thumbnail-server
Two new services on LXC 125's docker stack:
- seafile-md-server (Pro extended metadata, internal-only on :8084)
- thumbnail-server (Pro accelerated thumbnails, bound to .185:8081)

Caddy now routes /thumbnail/* to the thumbnail-server; everything else stays
on the main seafile container. End-to-end smoke verified: routing works,
per-request permission checks via INNER_SEAHUB_SERVICE_URL=http://seafile
correctly return 403 for cross-user thumbnail requests.
2026-05-12 19:06:50 +02:00
Claudio on hubris
02ad003e52 seafile: CE -> Pro upgrade, ES, Caddy resumable-upload fix
Same-day-as-deploy upgrade: image swapped to seafileltd/seafile-pro-mc:13.0-latest, elasticsearch:8.15.0 added as new compose service for Pro's full-text search. Free Pro tier (<=3 users, no license). Existing data + users survived.

Also documented the Caddy patch stripping IETF resumable-upload headers (Upload-Draft-Interop-Version etc.) so the iOS Seafile Pro 4.0.2 app falls back to plain multipart upload; without it large uploads stalled and cancelled after ~60s.
2026-05-12 18:45:56 +02:00
Claudio on hubris
40f6c93fd5 Add 125 (seafile) — Nextcloud-replacement evaluation
LXC 125 stood up as a Seafile CE 13.0 docker-compose deployment, behind
files.hubris.network. Authentik OAuth wired up via ak shell. No data
migration — exploration alongside Nextcloud (114).
2026-05-12 12:45:45 +02:00
claudio
bb410eea49 120 mule-images: Phase 4 — retire /data/thumbs; SECRET_KEY bug fix
- Vision fetches NC preview at 640px via new sync helper.
- WORKER_THUMB_SIZES = set(); generate_thumbnails still does pHash.
- All medium.webp purged after verification.
- Bug: SECRET_KEY was missing from workers in compose, so
  Fernet decrypt silently failed everywhere outside the backend
  container. Phase 3 had been falling back to ExifTool the whole
  time. Fix replicates SECRET_KEY to all worker services.
2026-05-11 14:00:50 +02:00
claudio
372b856b32 120 mule-images: Phase 3 — extract_metadata via Memories HTTP API
Tries Memories /api/image/info/{fileid} first (OCS-APIRequest header
bypasses CSRF), falls back to ExifTool on 404 / non-NC / errors.
Kept the full date-fallback chain because 35% of the library uses
filename-encoded dates that Memories doesn't recover.
2026-05-11 13:41:54 +02:00
claudio
599715a447 120 mule-images: folder rename round-trip both ways
- handle_directory_rename in scan.py covers NC-side renames via the
  webhook. Iterates rows in Python (asyncpg int-type quirk on raw
  SUBSTRING+LENGTH).
- Existing PATCH /folders/{id} handles mule-side renames; webhook
  feedback hits the same helper and is a 0-row no-op (idempotent).
2026-05-11 13:19:05 +02:00