investigations: add moonlight/sunshine WiFi jitter report + index entry
- New investigation doc: 2026-06-03-moonlight-sunshine-wifi-jitter.md - Updated investigations/index.md with link and status - Added .gitignore for .DS_Store - Saved Hermes planning docs from recent sessions
This commit is contained in:
@@ -0,0 +1,277 @@
|
||||
# Plan: Migrate library SSD to ludo-mini + Proxmox gaming/media server
|
||||
|
||||
## Goal
|
||||
|
||||
Split the homelab into two Proxmox hosts:
|
||||
|
||||
| Host | Role | Storage |
|
||||
|------|------|---------|
|
||||
| **hubris** | Core services (reverse-proxy, SSO, Matrix, git, documents, HA) | SSD 1 — boot + LXC rootfs (unchanged) |
|
||||
| **ludo-mini** | Gaming server + media/library services | SSD 2 — Samsung 990 EVO Plus 4 TB (moved from hubris) |
|
||||
|
||||
The library SSD physically moves from hubris to ludo-mini. hubris LXCs that still need `/mnt/library` access it over NFS from ludo-mini.
|
||||
|
||||
## Current state
|
||||
|
||||
### hubris hardware
|
||||
- GMKtec NucBox M6 Ultra — AMD Ryzen 5 7640HS, 12 vCPU, ~28 GiB RAM
|
||||
- 2× Samsung 990 EVO Plus NVMe:
|
||||
- nvme0: `local` (95G) + `local-lvm` (856G) — boot, ISOs, LXC rootfs
|
||||
- nvme1: `library` LVM (3.7T) — `/mnt/library` ext4 via `/dev/mapper/library-library`
|
||||
|
||||
### LXCs binding `/mnt/library` (host-level bind-mount)
|
||||
| ID | Name | Role | I/O profile |
|
||||
|----|------|------|-------------|
|
||||
| 101 | jellyfin | Media streaming | Read-heavy, sequential |
|
||||
| 103 | paperless | Document archive | Mixed, OCR writes |
|
||||
| 104 | gitea | Git server | Mixed, lots of small files |
|
||||
| 105 | apps | Docker (booklore, audiobookshelf, artifacto, MCP) | Mixed, depends on container |
|
||||
| 114 | nextcloud | File sync | Mixed, WebDAV |
|
||||
| 119 | sophia | Workshop | Low I/O |
|
||||
| 120 | mule-images | Photo management | Write-heavy (processing), iGPU |
|
||||
| 122 | arriman | *arr stack + downloads | Write-heavy (downloads) |
|
||||
| 126 | plato | App (sub-mount: `/mnt/library/documents/plato`) | Light |
|
||||
|
||||
### NFS export chain (for VM 100 zimaos)
|
||||
```
|
||||
/mnt/library (ext4, host) → bind-mount → LXC 102 (nfs-export) → NFSv4 → VM 100 (zimaos)
|
||||
```
|
||||
|
||||
### ludo-mini current
|
||||
- Linux workstation, wired Ethernet 2.5 Gbps, `192.168.178.181` (household LAN)
|
||||
- Runs Sunshine for game streaming
|
||||
- No Proxmox, no LVM config
|
||||
- Connected to SODOLA switch (same switch as hubris eno1)
|
||||
|
||||
### Network topology
|
||||
```
|
||||
Fritz!Box 7590 (192.168.178.1)
|
||||
└── SODOLA 2.5G switch
|
||||
├── hubris eno1 → vmbr1 (192.168.178.10)
|
||||
│ └── routes to vmbr0 (192.168.8.0/24) — all LXCs
|
||||
└── ludo-mini (192.168.178.181)
|
||||
```
|
||||
|
||||
hubris routes between `192.168.8.0/24` (vmbr0) and `192.168.178.0/24` (vmbr1). So LXCs can reach ludo-mini via hubris as a router.
|
||||
|
||||
## Key decisions
|
||||
|
||||
### 1. Service split — what moves, what stays
|
||||
|
||||
**Move to ludo-mini** (high I/O, benefits from data locality + GPU):
|
||||
- 101 jellyfin — media streaming, GPU transcoding
|
||||
- 120 mule-images — photo processing, iGPU passthrough
|
||||
- 122 arriman — *arr stack, downloads write to library
|
||||
|
||||
**Stay on hubris, NFS-mount library from ludo-mini:**
|
||||
- 103 paperless — documents, moderate I/O
|
||||
- 104 gitea — git repos (small files, some I/O sensitivity but acceptable over NFS)
|
||||
- 105 apps — Docker apps, mixed workloads
|
||||
- 114 nextcloud — file sync
|
||||
- 119 sophia — workshop, light use
|
||||
- 126 plato — app, light use
|
||||
- 100 zimaos — NAS frontend, already NFS-mounted
|
||||
|
||||
### 2. NFS architecture
|
||||
|
||||
Instead of changing every LXC's mount config, keep the bind-mount pattern on hubris:
|
||||
|
||||
```
|
||||
ludo-mini: /mnt/library (ext4, local NVMe)
|
||||
│
|
||||
└── NFSv4 export to 192.168.8.0/24
|
||||
│
|
||||
└── hubris host: NFS-mount at /mnt/library
|
||||
│
|
||||
└── LXCs: bind-mount /mnt/library (unchanged!)
|
||||
```
|
||||
|
||||
This is transparent to all hubris LXCs — no container config changes needed. Only the hubris host changes from ext4 local mount to NFS mount. The LXC bind-mounts "just work" because `/mnt/library` is still at the same path on the host.
|
||||
|
||||
### 3. Network — ludo-mini reachability from hubris LXCs
|
||||
|
||||
LXCs on `192.168.8.0/24` reach ludo-mini (`192.168.178.181`) through hubris routing:
|
||||
- `vmbr0` → hubris kernel routing → `vmbr1` → SODOLA → ludo-mini
|
||||
- Already works (IP forwarding enabled on hubris)
|
||||
|
||||
**Alternative (cleaner):** Add a secondary IP `192.168.8.x` on ludo-mini's physical interface so it's directly on the homelab subnet. This avoids the router hop and keeps NFS traffic off kernel forwarding path. Worth considering but not required.
|
||||
|
||||
### 4. Gaming on ludo-mini with Proxmox
|
||||
|
||||
ludo-mini runs Sunshine (game streaming). Under Proxmox:
|
||||
- **Option A:** Gaming VM with GPU passthrough — Sunshine + games in a VM, full GPU access
|
||||
- **Option B:** LXC with GPU device passthrough (`/dev/dri`) — lighter, shares kernel
|
||||
- **Option C:** Keep Sunshine on the Proxmox host itself (not recommended, but simplest)
|
||||
|
||||
Option A is the cleanest for isolation. Games need a full desktop environment and GPU drivers; a VM with GPU passthrough gives them that.
|
||||
|
||||
### 5. What about nfs-export (LXC 102)?
|
||||
|
||||
Currently exports `/mnt/library` to zimaos. After migration:
|
||||
- If zimaos stays on hubris and accesses library via host NFS → bind-mount → LXC 102, that's triple-hop (ludo-mini → NFS → hubris → bind-mount → LXC 102 → NFS → zimaos). Terrible.
|
||||
- Better: zimaos NFS-mounts directly from ludo-mini.
|
||||
- So LXC 102 gets decommissioned (or repurposed).
|
||||
- zimaos gets a new NFS mount pointing directly at ludo-mini.
|
||||
|
||||
## Migration phases
|
||||
|
||||
### Phase 1 — Preparation (no downtime)
|
||||
|
||||
1. **Document current state** on hubris:
|
||||
- `pct list` — full container inventory
|
||||
- `pct config <id>` for every library-mounting LXC
|
||||
- `cat /etc/fstab` — capture the library mount line
|
||||
- `df -h /mnt/library` — confirm space usage
|
||||
- `lsblk -f` — UUID, filesystem
|
||||
- Identify the exact NVMe device (`nvme1n1`)
|
||||
|
||||
2. **Pre-flight on ludo-mini:**
|
||||
- Confirm hardware: CPU, RAM, available M.2 slots, GPU model
|
||||
- Confirm it can take the Samsung 990 EVO Plus (M.2 NVMe, PCIe 4.0 x4)
|
||||
- Verify BIOS supports virtualization (VT-d/AMD-Vi for PCIe passthrough)
|
||||
- Check: does ludo-mini have a second drive for Proxmox OS? If not, we need to partition the library SSD for Proxmox boot + library LVM, which complicates things significantly
|
||||
|
||||
3. **Install Proxmox on ludo-mini:**
|
||||
- Download Proxmox VE 9.x ISO
|
||||
- Install to ludo-mini's system drive (NOT the library SSD)
|
||||
- Configure networking: bridge for Proxmox, IP on 192.168.178.x
|
||||
- Test: web UI accessible
|
||||
|
||||
4. **Prepare NFS server on ludo-mini Proxmox:**
|
||||
- Create NFS-export LXC (or serve from host — simpler for now)
|
||||
- Prepare `/etc/exports`: `192.168.8.0/24(rw,all_squash,anonuid=33,anongid=10000,no_subtree_check,sec=sys)`
|
||||
- Same squash params as current nfs-export LXC 102
|
||||
|
||||
### Phase 2 — Physical SSD move (planned downtime)
|
||||
|
||||
1. **Graceful shutdown on hubris:**
|
||||
- Stop all library-mounting LXCs (101, 103, 104, 105, 114, 119, 120, 122, 126)
|
||||
- Unmount `/mnt/library` on hubris host
|
||||
- Edit `/etc/fstab` to comment out the library mount line
|
||||
- Power off hubris
|
||||
|
||||
2. **Physical drive swap:**
|
||||
- Remove Samsung 990 EVO Plus (library SSD) from hubris
|
||||
- Install into ludo-mini M.2 slot
|
||||
- Power on ludo-mini
|
||||
|
||||
3. **Bring library online on ludo-mini:**
|
||||
- Detect the new NVMe device
|
||||
- If it's the whole device with LVM, activate the VG:
|
||||
```
|
||||
vgscan && vgchange -ay library
|
||||
mount /dev/mapper/library-library /mnt/library
|
||||
```
|
||||
- Add to `/etc/fstab` for auto-mount
|
||||
- Verify content: `ls /mnt/library` — same tree as before
|
||||
|
||||
4. **Start NFS export on ludo-mini:**
|
||||
- `exportfs -ra`
|
||||
- Verify: `showmount -e <ludo-mini-ip>`
|
||||
|
||||
### Phase 3 — Reconnect hubris LXCs
|
||||
|
||||
1. **Power on hubris** (without library SSD — it'll boot fine, just won't mount library)
|
||||
|
||||
2. **Mount NFS on hubris host:**
|
||||
- Install `nfs-common` if not present
|
||||
- Add to `/etc/fstab`:
|
||||
```
|
||||
192.168.178.181:/mnt/library /mnt/library nfs rw,vers=4,soft,timeo=30,retrans=3 0 0
|
||||
```
|
||||
Use `soft` to prevent hangs if ludo-mini is down; `hard` with `intr` is safer for data integrity but can block processes.
|
||||
- `mount /mnt/library`
|
||||
- **Verify permissions:** `ls -la /mnt/library` — should show `www-data:media` ownership for shared subtrees (same uid 33, gid 10000). The NFS all_squash guarantees this.
|
||||
|
||||
3. **Start LXCs:**
|
||||
- Start the LXCs that stayed on hubris (103, 104, 105, 114, 119, 126)
|
||||
- Their bind-mounts should work — `/mnt/library` is populated via NFS
|
||||
- Verify each service: web UIs, git clone, document access
|
||||
|
||||
4. **Update DNS/Caddy** for services that moved:
|
||||
- If jellyfin, arr services moved to ludo-mini, update Caddyfile to point to ludo-mini IPs
|
||||
- Update DNS entries if needed
|
||||
|
||||
### Phase 4 — Migrate services to ludo-mini
|
||||
|
||||
1. **Create LXCs/VM on ludo-mini Proxmox:**
|
||||
- 101 jellyfin — privileged LXC, mount `/mnt/library`, add `media` group
|
||||
- 120 mule-images — privileged LXC, mount `/mnt/library` + `/dev/dri` passthrough
|
||||
- 122 arriman — privileged LXC, mount `/mnt/library`
|
||||
|
||||
2. **Migrate configs:**
|
||||
- Copy LXC configs from hubris (`/etc/pve/lxc/<id>.conf`) as templates
|
||||
- Adjust network (IPs on household subnet or Proxmox bridge)
|
||||
- Restore app data from backups or copy over NFS
|
||||
|
||||
3. **Gaming VM:**
|
||||
- Create VM with GPU passthrough
|
||||
- Pass through the dGPU for gaming performance
|
||||
- Install Sunshine + game libraries
|
||||
- Storage: VM disk on Proxmox storage, games on library SSD
|
||||
|
||||
4. **Update reverse proxy:**
|
||||
- Caddy on hubris (121): update backend IPs for jellyfin, jellyseerr, qbit, sab, mule-images → point to ludo-mini
|
||||
- Test: `media.hubris.network` serves from ludo-mini jellyfin
|
||||
|
||||
### Phase 5 — Cleanup
|
||||
|
||||
1. **Decommission nfs-export LXC 102** on hubris (no longer needed)
|
||||
2. **Update zimaos (100)** — change NFS mount from `192.168.8.200` → `192.168.178.181`
|
||||
3. **Remove old LXCs** from hubris (101, 120, 122) after confirming migration works
|
||||
4. **Update inventory.yaml:**
|
||||
- ludo-mini: `kind: proxmox-host`, add mounts/storage, add LXCs
|
||||
- Move services from hubris to ludo-mini
|
||||
- Remove nfs-export
|
||||
5. **Update DNS:** `nfs-export.hubris.network` → ludo-mini IP (or remove)
|
||||
6. **Run `homelab sync`** to propagate changes
|
||||
|
||||
## Open questions / unknowns
|
||||
|
||||
1. **Does ludo-mini have a second drive for Proxmox OS?** If not, we'd need to repartition the library SSD — carve out ~100 GB for Proxmox, then the rest for library LVM. This is risky (data loss if partitioning goes wrong) and requires a full backup first. **Alternative:** Buy a small SSD for ludo-mini's OS.
|
||||
|
||||
2. **What GPU does ludo-mini have?** Proxmox GPU passthrough requires IOMMU support and a GPU that doesn't have the reset bug. Need to check the exact GPU model.
|
||||
|
||||
3. **NFS performance for git (gitea)?** Git operations over NFS can be problematic (locking, stat() storms). Gitea bare repos at `/mnt/library/repos/*.git` might need testing. Worst case: move gitea's repo storage to local disk and keep `/mnt/library` for large file/LFS storage only.
|
||||
|
||||
4. **Media permission drift.** NFS `all_squash,anonuid=33,anongid=10000` ensures all writes from hubris LXCs (over NFS) and ludo-mini LXCs (local) land as `www-data:media`. This is the same squash currently used by nfs-export (102). Should be fine.
|
||||
|
||||
5. **ludo-mini network — add 192.168.8.x address?** Adding a secondary IP on ludo-mini's interface directly on the homelab subnet avoids routing through hubris for NFS traffic. Cleaner, but requires Proxmox bridge setup. Worth doing during Proxmox install.
|
||||
|
||||
6. **Sunshine migration.** Currently runs on ludo-mini bare metal. After Proxmox install, it needs to run in a VM. What happens to existing Sunshine configs, game libraries, save files? Need to preserve these during the Proxmox install.
|
||||
|
||||
7. **Backup before moving.** The library SSD holds 3.7 TB of irreplaceable data (documents, photos, repos). Restic backups are currently disabled. **Before physically moving the drive, verify the data is readable and consider doing one backup** — or at minimum, `rsync` critical directories.
|
||||
|
||||
## Files affected
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `/opt/homelab-context/inventory.yaml` | ludo-mini: workstation → proxmox-host; add LXCs, mounts; remove nfs-export; move service backends |
|
||||
| `/opt/homelab-context/hosts/hubris.md` | Remove library storage, add NFS mount note |
|
||||
| `/opt/homelab-context/hosts/ludo-mini.yaml` | Complete rewrite — Proxmox host, storage, tenants |
|
||||
| `/opt/homelab-context/containers/102-nfs-export.md` | Mark decommissioned |
|
||||
| `/opt/homelab-context/containers/index.md` | Move 101, 120, 122 to ludo-mini; remove 102 |
|
||||
| `/opt/homelab-context/infrastructure/dns.md` | Update nfs-export entry |
|
||||
| `/opt/homelab-context/infrastructure/media-permissions.md` | Note NFS squash from ludo-mini, not hubris |
|
||||
| hubris `/etc/fstab` | Replace ext4 mount with NFS mount |
|
||||
| ludo-mini `/etc/fstab` | Add library ext4 mount |
|
||||
| ludo-mini `/etc/exports` | Add NFS export config |
|
||||
| caddy (LXC 121) Caddyfile | Backend IPs for moved services |
|
||||
| DNS (LXC 107 Technitium) | Update entries for moved services |
|
||||
|
||||
## Validation checklist
|
||||
|
||||
- [ ] ludo-mini Proxmox web UI accessible
|
||||
- [ ] Library SSD detected and mountable on ludo-mini
|
||||
- [ ] NFS export from ludo-mini: `showmount -e <ip>` shows `/mnt/library`
|
||||
- [ ] hubris host NFS mount: `df -h /mnt/library` shows NFS, not ext4
|
||||
- [ ] hubris LXCs start and bind-mount /mnt/library (content visible)
|
||||
- [ ] gitea: `git clone` over SSH works, repos readable
|
||||
- [ ] paperless: document ingestion works, OCR processing
|
||||
- [ ] nextcloud: file sync, WebDAV
|
||||
- [ ] jellyfin: media plays from ludo-mini, transcoding works
|
||||
- [ ] arriman: downloads write to library, jellyfin picks up new media
|
||||
- [ ] mule-images: photo import and processing
|
||||
- [ ] zimaos: NFS mount from ludo-mini works, Files UI shows library
|
||||
- [ ] Sunshine: game streaming from ludo-mini VM works
|
||||
- [ ] All `*.hubris.network` services resolve and load through Caddy
|
||||
271
.hermes/plans/2026-06-03_150000-homelab-structure-revision.md
Normal file
271
.hermes/plans/2026-06-03_150000-homelab-structure-revision.md
Normal file
@@ -0,0 +1,271 @@
|
||||
# Homelab structure revision & improvement plan
|
||||
|
||||
## Goal
|
||||
|
||||
Identify structural issues in the current hubris homelab topology and propose an
|
||||
actionable improvement roadmap — DNS consolidation, monitoring gaps, backup
|
||||
recovery, mesh completion, resource rightsizing, and operational hygiene.
|
||||
|
||||
---
|
||||
|
||||
## Current state summary
|
||||
|
||||
| Dimension | Status |
|
||||
|-----------|--------|
|
||||
| Hypervisor | hubris (single-node Proxmox) — also does subnet routing (192.168.8.0/24) |
|
||||
| LXCs | 14 active, 1 retired (124), 1 new (107 dns) |
|
||||
| VMs | HAOS (108), ZimaOS (100) |
|
||||
| Workstations | mac-mini (macOS), republic-laptop, ludo-mini |
|
||||
| VPS | 1 IONOS box — netbird mgmt+signal+relay, traefik, authentik, coturn |
|
||||
| Switch | SODOLA 5-Port 2.5Gbit (L2, flat) |
|
||||
| Networking | 192.168.8.0/24 internal, fr!tz box main LAN via vmbr0→vmbr1 routing |
|
||||
| Mesh | Netbird + Tailscale (migrating), ~mixed state |
|
||||
| DNS | 3 sources: Technitium (CT 107), NetBird managed zone, public IONOS |
|
||||
| Backups | DISABLED since 2026-04-22 |
|
||||
| Monitoring | claudio-monitor (host health only, no apt/docker checks yet) |
|
||||
| Agent enrollment | 3/19 hosts enrolled (hubris, apps, republic-laptop) |
|
||||
|
||||
---
|
||||
|
||||
## Issues identified
|
||||
|
||||
### 1. Three overlapping DNS sources (highest risk)
|
||||
|
||||
**Problem:** Technitium on CT 107, NetBird managed DNS zone, and the public
|
||||
IONOS wildcard all answer `*.hubris.network` queries. The dns.md doc still
|
||||
references the old dnsmasq on LXC 124 (though the change log says it moved).
|
||||
NetBird's managed DNS bypasses Technitium entirely for some app names — there
|
||||
is no single source of truth for DNS.
|
||||
|
||||
**Risk:** Mismatched answers → services unreachable → "works on some clients
|
||||
but not others" debugging sessions. Already cost time when `auth.hubris.network`
|
||||
re-pointed to the VPS.
|
||||
|
||||
**Proposal:**
|
||||
- Phase out NetBird managed DNS zone for `hubris.network` — Technitium is the
|
||||
authoritative answerer for mesh & LAN clients
|
||||
- Set Technitium as the sole DNS for all LXCs (remove router DNS / Tailscale
|
||||
MagicDNS fallbacks)
|
||||
- Document the full authoritative chain: Technitium → upstream forwarders → public
|
||||
- Track Technitium config in git (dtoro/technitium-config or equivalent)
|
||||
|
||||
### 2. Backups disabled with no alternative (data loss risk)
|
||||
|
||||
**Problem:** The only backup was restic to an external USB that caused host
|
||||
crashes. It was disabled 2026-04-22 as an A/B test — host stability was
|
||||
confirmed by the SODOLA migration (no more Slate AX double-NAT hangs). The
|
||||
drive is still removed.
|
||||
|
||||
**Risk:** `/mnt/library` (~429 GB of irreplaceable data: photos, documents,
|
||||
git repos, gitea data) has no off-host copy. Single-disk failure = total loss.
|
||||
|
||||
**Proposal:**
|
||||
- Re-evaluate the USB drive stability with the new SODOLA switch topology
|
||||
(direct rear USB 3.0 port, no hub chain)
|
||||
- OR adopt a cloud-backed strategy: `rclone`-to-Hetzner Storage Box or
|
||||
Backblaze B2 for the irreplaceable subset (docs, photos, gitea data)
|
||||
- OR use hubris's own `zfs send` to a second host/disk if ZFS is feasible
|
||||
- Minimum viable: at minimum restore gitea backups + sops-encrypted secrets
|
||||
via an off-site cron (cheap B2 bucket)
|
||||
|
||||
### 3. Mesh migration still incomplete
|
||||
|
||||
**Problem:** Most LXCs still use Tailscale. This forces per-LXC DNS workarounds
|
||||
(/etc/hosts overrides, local dnsmasq) and runs two VPN stacks in parallel.
|
||||
Mesh migration doc (mesh.md) is comprehensive but execution stalled.
|
||||
|
||||
**Proposal:**
|
||||
- Batch-migrate all LXCs from Tailscale to Netbird in one maintenance window
|
||||
- Remove Tailscale from the PVE host
|
||||
- Ensure all LXCs resolve `*.hubris.network` via Technitium (no more /etc/hosts
|
||||
overrides)
|
||||
- Document Netbird client on each LXC (netbird version, setup key rotation)
|
||||
|
||||
### 4. LXC resource imbalance & disk pressure
|
||||
|
||||
**Problem:**
|
||||
| LXC | Cores | RAM | Rootfs | Disk usage |
|
||||
|-----|-------|-----|--------|------------|
|
||||
| mule-images (120) | 6 | 12 GiB | 60 GiB | photo AI, reasonable |
|
||||
| arriman (122) | 4 | 8 GiB | 24 GiB | media stack, OK |
|
||||
| nextcloud (114) | 4 | 6 GiB | 25 GiB | file sync, OK |
|
||||
| apps (105) | 2 | 4 GiB | 30 GiB | 6+ services, tight |
|
||||
| paperless (103) | 2 | 3 GiB | 8 GiB | 86.9% disk |
|
||||
| elementsynapse (118) | 1 | 2 GiB | 8 GiB | 86.8% disk |
|
||||
| gitea (104) | 1 | 1 GiB | 8 GiB | git server, adequate |
|
||||
| caddy (121) | 1 | 512 MiB | 6 GiB | fine for reverse proxy |
|
||||
|
||||
Paperless (103) and elementsynapse (118) are at critical disk levels. apps (105)
|
||||
is undersized for 6+ services.
|
||||
|
||||
**Proposal:**
|
||||
- Resize rootfs on paperless (8→16 GiB) and elementsynapse (8→16 GiB)
|
||||
- Bump apps (105) to 4 cores / 6 GiB RAM / 40 GiB rootfs
|
||||
- Enable claudio-monitor's disk check to alert before next crisis
|
||||
|
||||
### 5. VPS is a single point of failure
|
||||
|
||||
**Problem:** One IONOS VM runs netbird management (control plane), traefik
|
||||
(public ingress), authentik (identity), and coturn (TURN relay). If it goes
|
||||
down: no remote mesh, no public services, no auth.
|
||||
|
||||
**Proposal:**
|
||||
- Document a VPS recovery runbook (how to restore from a known-working backup)
|
||||
- Consider splitting authentik into a separate host or at minimum having a
|
||||
standby configuration
|
||||
- Not a high priority (the VPS has been stable) but worth documenting the
|
||||
blast radius and recovery path
|
||||
|
||||
### 6. No centralized logging
|
||||
|
||||
**Problem:** Each LXC has independent journald. Cross-service debugging
|
||||
involves hopping between `pct exec <id> -- journalctl -u <service>`. There is
|
||||
no aggregation or retention.
|
||||
|
||||
**Proposal:**
|
||||
- Deploy a lightweight log shipper (Loki + promtail, or vector.dev) on each LXC
|
||||
- Ship logs to a central Loki instance on apps (105) or a new small LXC
|
||||
- Grafana dashboard optional — even a simple `logcli` query saves time
|
||||
|
||||
### 7. Agent enrollment incomplete
|
||||
|
||||
**Problem:** Only hubris, apps, and republic-laptop are enrolled in the
|
||||
homelab-context system (age keys, sync timers, MCP access). mac-mini,
|
||||
ludo-mini, claudio-bot, and all other LXCs are not.
|
||||
|
||||
**Proposal:**
|
||||
- Batch-enroll remaining LXCs (jellyfin, paperless, gitea, nextcloud, etc.)
|
||||
- Enroll mac-mini (macOS — exercises the launchd timer path)
|
||||
- Enroll ludo-mini (needs SSH user config in inventory first)
|
||||
- Wire claudio-bot into inventory-aware queries
|
||||
|
||||
### 8. Configuration drift on untracked configs
|
||||
|
||||
**Problem:** Technitium config, dnsmasq (legacy), and several service-specific
|
||||
configs are not git-tracked.
|
||||
|
||||
**Proposal:**
|
||||
- Track Technitium zone backup + compose config in a git repo
|
||||
- Apply the same pattern as caddy-conf: dtoro/technitium-conf with auto-deploy
|
||||
|
||||
### 9. No capacity planning / resource monitoring
|
||||
|
||||
**Problem:** No trend data on CPU, RAM, or disk growth. The 86% disk alerts
|
||||
were discovered reactively. Rootfs resize is painful (requires Proxmox stop +
|
||||
resize + growfs inside).
|
||||
|
||||
**Proposal:**
|
||||
- Enable the missing claudio-monitor checks (disk growth trend, apt upgradable
|
||||
counts, docker image drift)
|
||||
- Set up a simple Prometheus + node_exporter on hubris or use the PVE API
|
||||
directly
|
||||
- At minimum, surface disk usage in the existing homelab-mcp management tools
|
||||
|
||||
### 10. No standard deploy / orchestration for bare-metal LXCs
|
||||
|
||||
**Problem:** Some services are bare-metal CLI apps (sophia, claudio-bot),
|
||||
some are Docker on apps (105), some are Portainer-managed. No consistent
|
||||
deploy pattern means every new service reinvents the deployment.
|
||||
|
||||
**Proposal:**
|
||||
- Don't over-engineer this — the current pragmatism works
|
||||
- Just document the decision tree:
|
||||
- Needs `/mnt/library` mount + heavy I/O → dedicated LXC
|
||||
- Small stateless web service → Docker on apps (105)
|
||||
- Media stack → dedicated LXC (arriman, jellyfin)
|
||||
- Everything else → judge by complexity
|
||||
|
||||
---
|
||||
|
||||
## Phased implementation plan
|
||||
|
||||
### Phase 1 — Critical fixes (this week)
|
||||
1. Resize rootfs on paperless (103) 8→16 GiB, elementsynapse (118) 8→16 GiB
|
||||
2. Enable claudio-monitor disk check + disk-growth alerting
|
||||
3. Pick one backup strategy and implement minimum viable (e.g. nightly
|
||||
gitea dump + sops-encrypted secrets to B2 via rclone)
|
||||
4. Verify Technitium is the sole DNS for all LXCs (remove NetBird managed zone
|
||||
for hubris.network)
|
||||
|
||||
### Phase 2 — Mesh consolidation (next week)
|
||||
5. Batch-migrate remaining LXCs from Tailscale to Netbird
|
||||
6. Remove Tailscale from PVE host
|
||||
7. Remove all per-LXC /etc/hosts DNS overrides
|
||||
8. Update DNS documentation to reflect Technitium as single source
|
||||
|
||||
### Phase 3 — Agent enrollment & logging (next 2 weeks)
|
||||
9. Enroll all LXCs in homelab-context (age keys, sync timers)
|
||||
10. Enroll mac-mini (macOS launchd path — exercises untested code path)
|
||||
11. Enroll ludo-mini
|
||||
12. Deploy log shipper (Loki + promtail) on apps (105) + all LXCs
|
||||
|
||||
### Phase 4 — Resource & monitoring hardening (next month)
|
||||
13. Resize apps (105) rootfs, bump RAM
|
||||
14. Deploy Prometheus + node_exporter or equivalent for trend data
|
||||
15. Track Technitium config in git with auto-deploy
|
||||
16. Write VPS recovery runbook
|
||||
|
||||
### Phase 5 — Drive re-evaluation (optional, behind host-stability gate)
|
||||
17. Re-attach USB backup drive with the new SODOLA topology (direct port)
|
||||
18. If stable for 7 days, re-enable restic backup schedule (chunked)
|
||||
19. If not stable, finalize cloud backup as permanent strategy
|
||||
|
||||
---
|
||||
|
||||
## Files likely to change
|
||||
|
||||
| Path | Change |
|
||||
|------|--------|
|
||||
| `/opt/homelab-context/inventory.yaml` | LXCs enrolled, resource updates |
|
||||
| `/opt/homelab-context/secrets/*.yaml` | New recipients for enrolled LXCs |
|
||||
| `/opt/homelab-context/infrastructure/dns.md` | Reflect Technitium as sole source |
|
||||
| `/opt/homelab-context/infrastructure/mesh.md` | Remove Tailscale references post-migration |
|
||||
| `/opt/homelab-context/infrastructure/backups.md` | New strategy |
|
||||
| `/opt/homelab-context/infrastructure/monitoring.md` | Enable missing checks |
|
||||
| `/opt/homelab-context/containers/103-paperless.md` | Rootfs resize |
|
||||
| `/opt/homelab-context/containers/118-elementsynapse.md` | Rootfs resize |
|
||||
| `/opt/homelab-context/containers/105-apps.md` | Resource bump, logging addition |
|
||||
| `/opt/homelab-context/containers/index.md` | Updated resource table |
|
||||
| `.sops.yaml` | New age pubkeys for enrolled LXCs |
|
||||
|
||||
## Verification
|
||||
|
||||
Each phase ends with a verification milestone:
|
||||
- Phase 1: `claudio-monitor` triggers on paperless disk → confirmed alert. Backup
|
||||
of gitea data lands in B2 (or equivalent). DNS query from any LXC returns
|
||||
Technitium answer.
|
||||
- Phase 2: `netbird status` shows all LXCs connected. Tailscale not running on
|
||||
PVE host. `curl auth.hubris.network` from any LXC resolves correctly without
|
||||
/etc/hosts.
|
||||
- Phase 3: Every LXC has `/opt/homelab-context/` + `/etc/age/key.txt`. MCP
|
||||
tools return valid host info for all enrolled LXC names. `journalctl` shows
|
||||
promtail shipping to Loki.
|
||||
- Phase 4: `claudio-monitor` shows disk growth trend. apps (105) can run all
|
||||
6+ services without OOM.
|
||||
|
||||
## Risks & tradeoffs
|
||||
|
||||
- **Netbird migration window:** All LXCs will briefly lose mesh connectivity
|
||||
during the Tailscale→Netbird cutover. Schedule in off-hours.
|
||||
- **Backup cost:** B2/e2 costs ~$5/month for ~500 GB. The USB drive was free
|
||||
but unstable — trade money for reliability.
|
||||
- **DNS consolidation:** Removing the NetBird managed DNS zone means any
|
||||
NetBird-specific names stop resolving for hubris.network — verify nothing
|
||||
depends on that path.
|
||||
- **Loki on apps (105):** Adds another container to an already-loaded host.
|
||||
May need to bump resources before deploying.
|
||||
- **Agent enrollment on every LXC:** Each enrollment creates an age keypair
|
||||
and commits a pubkey to inventory. Process is scriptable via `homelab client
|
||||
add` but still takes ~2 min per host for verification.
|
||||
|
||||
## Open questions
|
||||
|
||||
1. Is the USB backup drive still physically attached to hubris? If not, the
|
||||
simplest "re-enable" path requires physically re-attaching it.
|
||||
2. Authentik is now on the VPS — is LXC 124 (old Authentik) still running or
|
||||
was it fully decommissioned? The dns.md changelog says "shut down" but
|
||||
index.md lists it as "running".
|
||||
3. What's the actual disk layout on hubris? nvme0n1, ZFS pool, mount structure
|
||||
— needed to plan rootfs resizes safely.
|
||||
4. Does the user want to keep Tailscale on any host for a specific reason, or
|
||||
is full Netbird migration the clear goal?
|
||||
Reference in New Issue
Block a user