- 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
368 lines
9.3 KiB
YAML
368 lines
9.3 KiB
YAML
# Homelab inventory — canonical structured topology.
|
|
#
|
|
# Single source of truth. hosts/*.yaml is generated from this file by
|
|
# mcp/build_host_files.py; do NOT edit those by hand.
|
|
#
|
|
# Conventions:
|
|
# - hostname keys MUST match the actual `hostname` of the machine (on
|
|
# macOS: `scutil --get LocalHostName` if set).
|
|
# - `os:` one of: linux, macos
|
|
# - `kind:` one of: proxmox-host, lxc, vm, workstation, external
|
|
# ("external" is reserved for hosts the homelab CLI manages via ssh but
|
|
# that aren't homelab clients themselves — e.g. the IONOS netbird VPS
|
|
# with no /etc/age/key.txt and no /opt/homelab-context clone.)
|
|
# - `mesh:` lists addresses the host is reachable at. Both `netbird` and
|
|
# `tailscale` are accepted during the migration (see infrastructure/mesh.md).
|
|
# Prefer netbird FQDNs over raw IPs.
|
|
# - `age_pubkey:` provisioned by secrets-issuance on first bootstrap and
|
|
# committed back via `homelab client add --finalize-pubkey <key>`.
|
|
# - When a service moves hosts, update only the `services:` section here;
|
|
# never duplicate addresses elsewhere.
|
|
# - `ssh.user:` per-host login user. Default is `root` if omitted (matches
|
|
# every LXC + the PVE host). Set explicitly for workstations whose login
|
|
# user differs from `root`. Used by the `homelab` CLI to build
|
|
# `user@host` and to inform anyone running raw `netbird ssh` (which
|
|
# defaults to the LOCAL username — the gotcha that creates "user not
|
|
# found" errors when ssh'ing INTO machines that only have `root`).
|
|
#
|
|
# `homelab client add/remove` does surgical line-edits — comments survive.
|
|
# Avoid round-tripping the file through yaml.safe_dump (it strips comments).
|
|
|
|
mesh:
|
|
primary: netbird
|
|
accepted:
|
|
- netbird
|
|
- tailscale
|
|
netbird_subnet: 100.122.0.0/16
|
|
netbird_domain: netbird.selfhosted
|
|
services:
|
|
proxmox_ui:
|
|
url: https://proxmox.hubris.network
|
|
backend: hubris
|
|
port: 8006
|
|
gitea:
|
|
url: https://git.hubris.network
|
|
backend: gitea
|
|
backend_url: http://192.168.8.121:3000
|
|
caddy:
|
|
backend: caddy
|
|
role: reverse-proxy
|
|
note: terminates all *.hubris.network
|
|
authentik:
|
|
url: https://auth.hubris.network
|
|
backend: authentik
|
|
dnsmasq:
|
|
backend: authentik
|
|
note: split-horizon DNS, /etc/dnsmasq.d/hubris-split.conf
|
|
jellyfin:
|
|
url: https://media.hubris.network
|
|
backend: jellyfin
|
|
nextcloud:
|
|
url: https://cloud.hubris.network
|
|
backend: nextcloud
|
|
paperless:
|
|
url: https://paperless.hubris.network
|
|
backend: paperless
|
|
matrix:
|
|
url: https://matrix.hubris.network
|
|
backend: elementsynapse
|
|
photos:
|
|
url: https://photos.hubris.network
|
|
backend: mule-images
|
|
plato:
|
|
url: https://plato.hubris.network
|
|
backend: plato
|
|
arr_stack:
|
|
backend: arriman
|
|
note: jellyseerr / qbit / sab on docker compose
|
|
artifacto:
|
|
backend: apps
|
|
url: https://artifacto.hubris.network
|
|
zimaos:
|
|
url: https://zimaos.hubris.network
|
|
backend: zimaos
|
|
haos:
|
|
backend: haos
|
|
homelab_mcp:
|
|
backend: apps
|
|
port: 9810
|
|
systemd_unit: homelab-mcp
|
|
public_host: mcp.hubris.network
|
|
endpoint: https://mcp.hubris.network/mcp
|
|
note: MCP server. Read-only context + management. Reachable on the LAN via Caddy
|
|
and from off-LAN via Netbird (192.168.8.0/24 is a network resource routed through
|
|
hubris).
|
|
secrets_issuance:
|
|
backend: apps
|
|
port: 9820
|
|
systemd_unit: secrets-issuance
|
|
public_host: secrets.hubris.network
|
|
endpoint: https://secrets.hubris.network/issue
|
|
note: Issues per-client age private keys. Gated at source-IP layer (mesh + LAN
|
|
subnets in MESH_SUBNETS).
|
|
hosts:
|
|
hubris:
|
|
kind: proxmox-host
|
|
os: linux
|
|
role: hypervisor
|
|
lan_ip: 192.168.8.77
|
|
mesh:
|
|
netbird:
|
|
ip: 100.122.38.109
|
|
fqdn: proxmox-server.netbird.selfhosted
|
|
ssh:
|
|
port: 22
|
|
netbird_port: 22022
|
|
user: root
|
|
mounts:
|
|
- /mnt/library
|
|
age_pubkey: age1xkklkvnk5z0fsnh6cfgv70hy9ksfy8rdprwerzw4yk3p4p7cxcqs2yvpz6
|
|
jellyfin:
|
|
kind: lxc
|
|
pve_id: 101
|
|
host: hubris
|
|
os: linux
|
|
role: media-server
|
|
lan_ip: 192.168.8.206
|
|
public_host: media.hubris.network
|
|
mesh:
|
|
tailscale:
|
|
fqdn: jellyfin
|
|
mounts:
|
|
- /mnt/library
|
|
age_pubkey: ''
|
|
nfs-export:
|
|
kind: lxc
|
|
pve_id: 102
|
|
host: hubris
|
|
os: linux
|
|
role: storage-export
|
|
lan_ip: 192.168.8.200
|
|
paperless:
|
|
kind: lxc
|
|
pve_id: 103
|
|
host: hubris
|
|
os: linux
|
|
role: document-archive
|
|
lan_ip: 192.168.8.130
|
|
public_host: paperless.hubris.network
|
|
mesh:
|
|
tailscale:
|
|
fqdn: paperless
|
|
mounts:
|
|
- /mnt/library
|
|
age_pubkey: ''
|
|
gitea:
|
|
kind: lxc
|
|
pve_id: 104
|
|
host: hubris
|
|
os: linux
|
|
role: git-server
|
|
lan_ip: 192.168.8.121
|
|
public_host: git.hubris.network
|
|
backend_port: 3000
|
|
mesh:
|
|
tailscale:
|
|
fqdn: gitea
|
|
mounts:
|
|
- /mnt/library
|
|
notes:
|
|
- Bare repos live at /mnt/library/repos/dtoro/*.git
|
|
age_pubkey: ''
|
|
apps:
|
|
kind: lxc
|
|
pve_id: 105
|
|
host: hubris
|
|
os: linux
|
|
role: docker-apps
|
|
lan_ip: 192.168.8.205
|
|
public_hosts:
|
|
- artifacto.hubris.network
|
|
mesh:
|
|
tailscale:
|
|
ip: 100.121.171.122
|
|
fqdn: apps
|
|
mounts:
|
|
- /mnt/library
|
|
runs:
|
|
- artifacto
|
|
- plantuml
|
|
- homelab-mcp
|
|
- secrets-issuance
|
|
age_pubkey: age1duyl8mkpgu80uv934dy8q7enqjms6yvdz264hme8uryuxmvvqesq6rusq0
|
|
nextcloud:
|
|
kind: lxc
|
|
pve_id: 114
|
|
host: hubris
|
|
os: linux
|
|
role: file-sync
|
|
lan_ip: 192.168.8.224
|
|
public_host: cloud.hubris.network
|
|
mesh:
|
|
tailscale:
|
|
fqdn: nextcloud
|
|
mounts:
|
|
- /mnt/library
|
|
age_pubkey: ''
|
|
elementsynapse:
|
|
kind: lxc
|
|
pve_id: 118
|
|
host: hubris
|
|
os: linux
|
|
role: matrix-server
|
|
lan_ip: 192.168.8.239
|
|
public_host: matrix.hubris.network
|
|
mesh:
|
|
tailscale:
|
|
fqdn: elementsynapse
|
|
sophia:
|
|
kind: lxc
|
|
pve_id: 119
|
|
host: hubris
|
|
os: linux
|
|
role: workshop
|
|
lan_ip: 192.168.8.157
|
|
mesh:
|
|
tailscale:
|
|
fqdn: sophia
|
|
mounts:
|
|
- /mnt/library
|
|
age_pubkey: ''
|
|
mule-images:
|
|
kind: lxc
|
|
pve_id: 120
|
|
host: hubris
|
|
os: linux
|
|
role: photo-management
|
|
lan_ip: 192.168.8.136
|
|
public_host: photos.hubris.network
|
|
mesh:
|
|
tailscale:
|
|
fqdn: muleimage
|
|
mounts:
|
|
- /mnt/library
|
|
age_pubkey: ''
|
|
caddy:
|
|
kind: lxc
|
|
pve_id: 121
|
|
host: hubris
|
|
os: linux
|
|
role: reverse-proxy
|
|
lan_ip: 192.168.8.175
|
|
notes:
|
|
- Terminates all *.hubris.network
|
|
- /etc/caddy is a git checkout of dtoro/caddy-conf
|
|
peers:
|
|
- authentik
|
|
- gitea
|
|
arriman:
|
|
kind: lxc
|
|
pve_id: 122
|
|
host: hubris
|
|
os: linux
|
|
role: arr-stack
|
|
lan_ip: 192.168.8.132
|
|
public_hosts:
|
|
- jellyseerr.hubris.network
|
|
- qbit.hubris.network
|
|
- sab.hubris.network
|
|
mesh:
|
|
tailscale:
|
|
fqdn: arr
|
|
mounts:
|
|
- /mnt/library
|
|
age_pubkey: ''
|
|
# 123 (claudio-bot) — destroyed 2026-06-04, replaced by Hermes Agent
|
|
authentik:
|
|
kind: lxc
|
|
pve_id: 124
|
|
host: hubris
|
|
os: linux
|
|
role: idp
|
|
lan_ip: 192.168.8.180
|
|
public_host: auth.hubris.network
|
|
notes:
|
|
- 'Also hosts split-horizon dnsmasq: /etc/dnsmasq.d/hubris-split.conf'
|
|
plato:
|
|
kind: lxc
|
|
pve_id: 126
|
|
host: hubris
|
|
os: linux
|
|
role: app
|
|
lan_ip: 192.168.8.190
|
|
public_host: plato.hubris.network
|
|
mounts:
|
|
- /mnt/library/documents/plato
|
|
age_pubkey: ''
|
|
zimaos:
|
|
kind: vm
|
|
pve_id: 100
|
|
host: hubris
|
|
os: linux
|
|
role: nas-frontend-eval
|
|
lan_ip: 192.168.8.195
|
|
public_host: zimaos.hubris.network
|
|
haos:
|
|
kind: vm
|
|
pve_id: 108
|
|
host: hubris
|
|
os: linux
|
|
role: home-automation
|
|
lan_ip: 192.168.8.101
|
|
mesh:
|
|
tailscale:
|
|
fqdn: homeassistant
|
|
republic-laptop:
|
|
kind: workstation
|
|
os: linux
|
|
role: primary-dev
|
|
mesh:
|
|
netbird:
|
|
fqdn: republic-laptop.netbird.selfhosted
|
|
ssh:
|
|
user: dtoro
|
|
mac-mini:
|
|
kind: workstation
|
|
os: macos
|
|
role: dev
|
|
lan_ip: 192.168.8.174
|
|
mesh:
|
|
netbird:
|
|
fqdn: mac-mini-234-17.netbird.selfhosted
|
|
ssh:
|
|
user: dtoro
|
|
notes:
|
|
- Only macOS in the fleet. Bootstrap uses launchd.
|
|
age_pubkey: age1z62ff2ak9zj5ctcvaxwyyhedwjvlwgm2dkn9nk3wrwk8fkavcpmsqwc2vs
|
|
ludo-mini:
|
|
kind: workstation
|
|
os: linux
|
|
role: dev
|
|
mesh:
|
|
netbird:
|
|
fqdn: ludo-mini.netbird.selfhosted
|
|
# ssh.user defaults to root; uncomment + set to the actual login user
|
|
# before relying on `homelab ssh ludo-mini` or netbird-ssh INTO this host.
|
|
# ssh: { user: ludo }
|
|
netbird-vps:
|
|
kind: external
|
|
os: linux
|
|
role: netbird-mgmt
|
|
mesh:
|
|
netbird:
|
|
ip: 100.122.165.149
|
|
fqdn: netbird-ionos.netbird.selfhosted
|
|
ssh:
|
|
user: root
|
|
notes:
|
|
- Public IONOS VPS — hosts the vanilla netbird mgmt+signal+relay+dashboard
|
|
stack + host coturn (see infrastructure/vps-hardening.md +
|
|
infrastructure/mesh.md changelog 2026-05-21).
|
|
- NOT a homelab client. No /etc/age/key.txt, no /opt/homelab-context
|
|
clone. Managed via ssh from hubris; sshd is locked to hubris's pubkey.
|
|
- Public IPv4 82.165.190.79. Auto-patching via unattended-upgrades.
|
|
- Configs rendered by `homelab render-vps-configs` from
|
|
vps/turnserver.conf.tmpl + vps/management.json.tmpl, with secrets
|
|
decrypted from secrets/turn-shared-secret.yaml +
|
|
secrets/netbird-authentik-oidc.yaml on hubris.
|