11 KiB
strong — Proxmox host
Second node in the Homelab cluster, alongside hubris. Formerly
a Linux dev workstation nicknamed "ludo" (or "ludo-mini") — reformatted to
Proxmox VE on 2026-07-01. No LXCs/VMs deployed on it yet.
At a glance
- Role: Proxmox VE 9.2.3 cluster member (kernel
7.0.12-1-pve) - Naming: the OS/cluster hostname is
strong(leftover from install, kept as-is). This wiki page andinventory.yamlalso usestrongas of 2026-07-01 — earlier the same day the inventory entry was briefly namedludo-mini, but that was renamed so the hostname bootstrap needs (hosts/$(hostname).yaml) would just resolve. "Ludo"/"ludo-mini" remains the machine's everyday nickname; some older docs (investigations, the library-SSD migration plan) still refer to it that way — that's fine, those are historical. - Hardware: AMD Ryzen 7 PRO 6850U, 16 threads, 28 GiB RAM.
nvme0n1— MasonSemi MC3100 1TB (boot/OS):pve-root96G,pve-data(thinpool) 815G, 8G swap.nvme1n1— WD_BLACK SN7100 2TB, added 2026-07-01. Arrived with an existing APFS partition (previously used in a Mac) — wiped viapvesh set nodes/strong/disks/wipedisk --disk /dev/nvme1n1, then turned into its own LVM-thin pool viapvesh create nodes/strong/disks/lvmthin(handles pvcreate/vgcreate/lvcreate + storage.cfg registration in one step). Registered as Proxmox storageludo-lvm(VGludo-lvm, thinpoolludo-lvm, ~1.8 TiB usable — kept theludo-lvmname since that's what was actually created live; not worth renaming), restrictednodes strongin/etc/pve/storage.cfg— same pattern as hubris'slibrarypool. Empty so far; this is separate from the library-SSD migration plan's planned drive move from hubris (that hasn't happened) — this is general-purpose VM/CT capacity.
- Network:
vmbr0is bridged straight onto the household LAN —192.168.178.181/24, gateway192.168.178.1. Unlike hubris, there is no internal/uplink bridge split yet —vmbr0here plays the role hubris'svmbr1plays there. Reachable from the homelab subnet (192.168.8.0/24) via the existing Fritz!Box static route through hubris; no new cabling or routing was needed to join the cluster. - Storage:
local+local-lvm(cluster-wide default names, shared with hubris by convention, actually separate per-node volumes). Hubris'slibrarylvmthin pool is restricted tonodes hubrisin/etc/pve/storage.cfgand does not exist here. - Mesh: Netbird not installed — fresh OS wiped whatever the old
workstation had. Reachable today only via LAN routing (confirmed DNS for
*.hubris.networkalready resolves correctly here via192.168.8.2). Add to Netbird if off-LAN access to this host itself (distinct from any future guests) is needed. - Homelab-context client enrollment: done 2026-07-01 via
bootstrap.sh --no-secrets(reused the operator's existing Gitea PAT for the initial clone)./opt/homelab-context, thehomelabCLI, and the 5-min sync timer are live;homelab whoamiresolves correctly. See agent-enrollment.md. - Age key / secrets: issued the same day over plain LAN (no Netbird
needed — see the
--no-meshbootstrap.sh fix below). Key lives at/etc/age/key.txt; pubkeyage1rtwvdct6avjkr3cyxv3vue3vqx4d524fjfr3vk7xrnvyrylnry5sm54sn4recorded ininventory.yaml. Not yet a recipient on any actual secret (hello.yaml,gitea-pat.yaml, etc.) — that's a separate grant, see "Granting a secret to a new client".
Cluster membership
Joined hubris's single-node cluster (Homelab) via pvecm add on
2026-07-01. See hosts/hubris.md#cluster for the full
cluster picture, node IDs, and the quorum tradeoff (2 nodes, no QDevice —
either node going down freezes management on the survivor).
SSH
Root login via the same key set trusted on hubris (root@hubris,
d.toro.v@pm.me) — installed 2026-07-01 by appending to
/root/.ssh/authorized_keys (now symlinked to /etc/pve/priv/authorized_keys
post cluster-join, so it's cluster-synced same as hubris). No password auth
needed going forward.
Related
- hubris — Proxmox host
- Library SSD migration plan — the larger project this is Phase 1 of (filename kept as-is, historical)
- Network
- SSH access
- Agent enrollment
Changelog
2026-07-05 — Phase 2d: grimmory (130) migrated to strong
Migrated book library from hubris (192.168.8.213) to strong (192.168.8.247). Rsync'd /books (2.6G) from hubris library SSD to ludo-lvm/media. Container mounts /mnt/media_local → /mnt/library locally. Caddy backend for books.hubris.network updated.
2026-07-05 — Phase 2: arriman (122) + jellyfin (101) migrated; library on ludo-lvm
Migrated arriman (→ 192.168.8.245) and jellyfin (→ 192.168.8.246) to strong. Created 1.5T thin volume on ludo-lvm for media library (/mnt/media_local). Rsync'd 363G of media data (movies, tv, anime, downloads, music) from hubris library SSD to ludo-lvm. Both containers now mount /mnt/media_local directly as local ext4 — no NFS cross-node dependency. Jellyfin gets Radeon 680M iGPU (for VAAPI) + RX 7600 dGPU passthrough via dev0/dev1. Caddy backends updated for media, jellyseerr, qbit, sab. Hubris freed 16 GiB RAM (8+8). Dhcp scope narrowed to 192.168.8.100-239.
2026-07-05 — house (LXC 129) migrated to strong; DHCP scope narrowed
Migrated Yuvomi family planner from hubris (192.168.8.212) to strong (192.168.8.244). Followed same restore pattern as elementsynapse (Phase 1b). Discovered IP conflict: teddycloud (LXC 131) had 192.168.8.243 via DHCP (scope was 192.168.8.241-254). Narrowed DHCP scope to 192.168.8.100-239, gave teddycloud static IP 192.168.8.150. Caddy updated: house.hubris.network → 192.168.8.244:3000, teddy.hubris.network → 192.168.8.150:8443.
2026-07-05 — elementsynapse (LXC 118) migrated to strong
Migrated Matrix/Synapse + Element client from hubris (192.168.8.239) to a new LXC on strong (192.168.8.242). Added vmbr1 on strong at 192.168.8.241/28 (portless internal bridge) for strong-hosted guests. Enabled IP forwarding, proxy ARP on hubris vmbr0, and specific /32 routes for strong's guest subnet. Caddy updated: element.hubris.network → 192.168.8.242:8080. VPS traefik updated: matrix.hubris.network backend → 192.168.8.242:8008. This is Phase 1a of the strong migration plan — see .hermes/plans/2026-07-05_strong-migration-assessment.md.
2026-07-01 — age key issued over LAN; 3 bugs found/fixed in bootstrap.sh
Re-ran bootstrap without --no-secrets to get a real age key. Hit three real bugs live, fixed all three in bootstrap.sh and re-ran clean:
- The
mcp-CLI pipx-install step and the (unused,--with-hermes-only) Goose installer both calledsudo -u <user>unconditionally — fails with "sudo: command not found" on a minimal root-only image with nosudobinary at all. Added arun_as()helper that only shells out tosudowhen there's a real distinct invoking user. sopsisn't an apt/dnf package (matches whatagent-enrollment.md's manual-install recipe already does) — the auto-installer triedapt-get install sopsand failed outright. Addedinstall_sops_binary(), fetching the GitHub release binary directly on both dnf and apt paths.- Bigger one: running without
--no-secretsunconditionally tries to install + interactively connect Netbird (device-code SSO), even though the very next check already knows how to accept plain LAN reachability instead. Over SSH with nobody watching, this hangs forever — had to manually kill a stucknetbird upprocess. Added--no-mesh, which skips the Netbird install/connect step but keeps the LAN-fallback path for secrets issuance. This run usedbootstrap.sh --no-meshand completed cleanly:mesh: lan, age key installed,mcpCLI installed via pipx (proving fix #1 too).
Result: age key at /etc/age/key.txt, pubkey recorded in inventory.yaml. Not yet granted access to any actual secret file — see the note above.
2026-07-01 — enrolled as a homelab-context client
Ran bootstrap.sh --no-secrets (reused the operator's existing personal Gitea PAT for the initial clone rather than minting a fresh read-only one). Installed git, cloned /opt/homelab-context, installed the 5-min systemd sync timer, symlinked homelab CLI and AGENTS.md. Skipped age-key/secrets issuance and Netbird per operator choice — but bootstrap's own connectivity check reported mesh: lan, i.e. the secrets-issuance endpoint is already reachable over plain LAN, so re-running without --no-secrets later wouldn't require a Netbird join. Known gap: the mcp pipx CLI install step silently failed (sudo: command not found — bootstrap.sh's pipx step assumes a sudo binary even when already root; harmless, only affects the homelab mcp <tool> shell subcommand).
2026-07-01 — inventory identity renamed ludo-mini → strong
Discovered while starting client enrollment: bootstrap.sh looks up
hosts/$(hostname).yaml, and the OS hostname here is strong, not
ludo-mini. Renaming the OS hostname was ruled out (already a cluster
member — Proxmox doesn't support in-place node rename, only leave+rejoin).
Renamed the wiki/inventory side instead: inventory.yaml key, this page
(hosts/ludo-mini.md → hosts/strong.md), README, ssh-access.md all now
say strong. "Ludo"/"ludo-mini" is still fine as a spoken nickname.
2026-07-01 — 2nd NVMe added; new LVM-thin pool ludo-lvm
User added a WD_BLACK SN7100 2TB (nvme1n1), previously used in a Mac
(arrived with an EFI + APFS partition table — confirmed disposable, wiped).
Used Proxmox's own disk-management API rather than raw LVM commands:
pvesh set nodes/strong/disks/wipedisk --disk /dev/nvme1n1 to clear the old
partition table/signatures, then pvesh create nodes/strong/disks/lvmthin --name ludo-lvm --device /dev/disk/by-id/nvme-WD_BLACK_SN7100_2TB_251663803202 --add_storage 1 to create the PV/VG/thinpool and register it as Proxmox
storage in one step. Result: storage ID ludo-lvm, ~1.8 TiB, content rootdir,images, nodes strong (mirrors hubris's library node-restriction
pattern — this pool only physically exists here). Empty — no VM/CT disks
placed on it yet.
2026-07-01 — Proxmox install; joined Homelab cluster
Reformatted from Linux workstation to Proxmox VE 9.2.3. SSH keys seeded from
hubris's trusted set (root password used once, then discarded). Joined the
existing Homelab cluster via pvecm add 192.168.8.77 --use_ssh 1 from
this node's side, using key-based SSH pre-authorized in both directions —
no interactive password prompt needed for the join itself. Cluster now 2
nodes (hubris, strong), quorate, no QDevice. Decided to leave hostname
as strong and skip a QDevice for now — both revisitable later.