dtoro 2ff7263f3d homelab: add apt-audit + apt-upgrade subcommands; fix hubris_ssh
Two new subcommands (B1+H1 + C1+C2 from the apt-sweep backlog):

* `homelab apt-audit [--target HOST]`
  Per-host pre-flight table reporting dpkg-interrupted state, holds,
  upgradable count, non-apt binaries in system paths, and DNS health.
  Exits nonzero if any target has unconfigured packages (would catch the
  latent dpkg-interrupted state we found on caddy + nextcloud before
  touching them).

* `homelab apt-upgrade [--target HOST | --all] [--status] [--force]`
  Launches `apt update && apt upgrade` inside a transient systemd unit
  (`apt-upgrade-<hostname>`) on each target via `systemd-run --collect`,
  so the run survives ssh teardown. Output tee'd to
  `/var/log/homelab-apt-upgrade.log`. Apt configured with
  `Acquire::Retries=3` + `ForceIPv4=true` to absorb transient mirror
  blips (would have prevented the jellyfin ffmpeg7 fetch failure that
  rolled back 131 packages mid-Wave-3).
  Pre-flight audit gate refuses to run on hosts with dpkg-interrupted
  state; override with --force.
  `--status` mode prints each target's unit state and tails the upgrade
  log; safe to run before, during, and after.

Also fixes a latent bug in `hubris_ssh()`: the function joined hubris's
`lan_ip` (192.168.8.77) with the netbird-only port 22022. Port 22022
listens on hubris's netbird interface ONLY — not on the LAN interface,
not even via the netbird subnet route. Result: every off-LAN client
hitting `homelab pct/logs/restart/status` got "Connection refused".
Now uses the netbird FQDN when netbird_port is in use; falls back to
host_address otherwise.

Targets exclude VMs and workstations (they have their own update flows).
Standard apt targets = hubris + every LXC (kind=lxc with a pve_id).

Validated 2026-05-21 on republic-laptop:
- apt-audit reported clean dpkg + 40 upgradable on hubris (the still-
  deferred PVE/kernel packages) + 0 on every LXC, DNS ok across the
  fleet
- apt-upgrade --target mule-photos-new launched the unit, ran apt to
  completion (0 upgrades pending), log captured with =START= / =END
  rc=0= markers, --status reports unit + log correctly
- --all --status fans out across all 16 targets without issue

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 09:08:25 +02:00
2026-05-20 19:29:47 +02:00
2026-05-20 19:29:47 +02:00
2026-04-28 22:53:09 +02:00

Homelab Wiki — hubris

Living documentation for the hubris Proxmox homelab. Every node, every cross-cutting system, and every meaningful incident is its own page; pages are linked so you can start anywhere and walk the graph.

Last refreshed against live state: 2026-04-28.

Map

Hosts

  • hubris — single Proxmox VE node, GMKtec NucBox M6 Ultra, 192.168.8.77

VMs

LXC containers

See the full table in containers/index.md. Quick links:

ID Name IP Role
101 jellyfin 192.168.8.206 Media server
102 nfs-export 192.168.8.200 NFSv4 re-export of /mnt/library for ZimaOS
103 paperless 192.168.8.130 Document mgmt
104 gitea 192.168.8.121 Git server
105 apps 192.168.8.205 Docker host (Artifacto / Booklore / PlantUML / Portainer / WriteFreely)
114 nextcloud 192.168.8.224 Personal cloud
118 elementsynapse 192.168.8.239 Matrix Synapse
119 sophia 192.168.8.157 Sophia
120 mule-images 192.168.8.136 Mule-image / mulita photos
121 caddy 192.168.8.175 Reverse proxy
122 arriman 192.168.8.132 Docker host (*arr stack)
123 claudio-bot 192.168.8.230 Matrix control plane
124 authentik 192.168.8.180 SSO + split-horizon DNS
126 plato 192.168.8.190 Plato (notes/discovery workspace)

Cross-cutting infrastructure

Investigations

Time-stamped incident notes / experiments in investigations/.

Operations

Conventions

  • Each node page ends with a ## Changelog section. Reverse-chronological. Entry format:
    ### YYYY-MM-DD — short title
    one or two lines on what changed and why.
    
  • Cross-linking is mandatory. If a page references another node or system, link to it. Treat orphans as a bug.
  • Live state wins. When something here disagrees with pct config / docker inspect / running config, fix the wiki and note the change in the relevant changelog.
  • Tracked configs. A node whose config lives in a Gitea repo (Caddy, Gitea customizations, Artifacto, mule-image, claudio-bot) is auto-deployed via webhook — see auto-deploy. Edits there must be pushed, not left local.
  • No secrets. This is a private repo on git.hubris.network, but still: paths to secret files are fine, secret values are not.

Maintaining this wiki

When you change a node:

  1. Update the relevant page (config snapshot, ports, mounts).
  2. Add a changelog entry at the bottom of that page.
  3. If the change touches a cross-cutting system (DNS, Caddy, Authentik, mesh), update that page too and link it from the changelog entry.
  4. If it's an incident, add an entry to investigations/.

See also

Description
Agentic OS for running a Homelab
Readme 37 MiB
Languages
Go 53.1%
Svelte 25.7%
TypeScript 14%
Shell 3.8%
Python 1.7%
Other 1.5%