Phase 1-4: full doc reorg
Phase 1 — fix stale state after strong migration (Phase 1+2, 2026-07-05)
- README: corrected IPs (jellyfin 206→246, arriman 132→245, etc.),
added missing containers (128 trmnl, 129 house, 133 seanime, 134 romm,
124 authentik), updated last-refreshed date, added strong host context
- containers/101-jellyfin.md: IP 206→246, host hubris→strong, mount
/mnt/library→/mnt/media_local, GPU 760M→680M+RX7600, privilege→priv
- containers/118-elementsynapse.md: IP 239→242, added Host: strong
- containers/122-arriman.md: IP 132→245, mount→/mnt/media_local, added Host
- containers/129-house.md: IP 212→244, added Host: strong
- containers/130-grimmory.md: IP 213→247, mount→/mnt/media_local, added Host
- containers/121-caddy.md: fixed site list (books→grimmory, removed auth→VPS,
added house, roms, teddy, trmnl)
- hosts/strong.md: updated At-a-glance to reflect 7 LXCs hosted
- containers/123-claudio-bot.md, 127-mule-photos-new.md: archived to
containers/archive/ (were destroyed LXCs with living pages)
- inventory.yaml: verified correct — no changes needed
Phase 2 — structural cleanup
- infrastructure/index.md: one-page overview of all cross-cutting systems
- runbooks/: moved runbook-budget-from-csv.md and runbook-dpkg-interrupted.md
from operations/ with YAML frontmatter added
- plans/done/: moved 4 completed plans out of active view; updated index
- vms/index.md: added VM index page
Phase 3 — navigation & discoverability
- GLOSSARY.md: term definitions (Authentik, Caddy, LXC, VAAPI, etc.)
- README: added table of contents, links to glossary + infrastructure index
- investigations/: archived 2 resolved cases (crash-loop, authentik-migration)
to investigations/archive/; updated index with active vs archived sections
Phase 4 — ongoing discipline
- CONTRIBUTING.md: documented same-session update rule with explicit checklist
- README: replaced full LXC table with summary + link to containers/index.md
(single source of truth; de-duplication)
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,4 +5,6 @@ __pycache__/
|
||||
# Regenerated every scheduler run (every 10 min); no audit value in the
|
||||
# diff. Signals (signals/*.jsonl) ARE tracked — this is just the ephemeral
|
||||
# health-probe cache. See oikos/scheduler.py.
|
||||
oikos/state.json
|
||||
oikos/state.json
|
||||
|
||||
.worktrees/
|
||||
@@ -121,3 +121,27 @@ Changelog entries to write, index status to update.
|
||||
- One entry per discrete change, even if you make several in one day.
|
||||
- If a change spans nodes, repeat the entry on each affected page (different perspective is fine).
|
||||
- Don't rewrite history — entries are append-only. Mistakes get a follow-up entry that supersedes them.
|
||||
|
||||
## Same-session update rule
|
||||
|
||||
When you make a change to a node — migrate an LXC, update an IP, change a
|
||||
mount, deploy a new service — **update every relevant doc page in the same
|
||||
session.** A change that touches a container page must also update:
|
||||
|
||||
- The `containers/index.md` table (IPs, host, mounts, status)
|
||||
- The `README.md` table (if the change affects listed columns)
|
||||
- The Caddy page site list (if the change affects `*.hubris.network` routing)
|
||||
- The DNS / ingress infrastructure pages (if the change affects routing)
|
||||
- The `hosts/{hubris,strong}.md` host page (if container count changes)
|
||||
- The `inventory.yaml` host entry (source of truth for the `hosts/*.yaml` generation)
|
||||
- The `infrastructure/topology.md` (generated from inventory, but regen if needed)
|
||||
|
||||
The pattern of updating only one page and leaving stale references on others
|
||||
is a bug. If you're doing a multi-step migration, document the intermediate
|
||||
state with a changelog entry that says "pending — will finalize after Phase
|
||||
N."
|
||||
|
||||
This rule is why Phase 2 of the strong migration (2026-07-05) caused
|
||||
widespread stale data: individual container pages were updated in the
|
||||
changelog but never had their At-a-glance sections, IPs, mount paths, or
|
||||
host attribution updated. Don't repeat that.
|
||||
|
||||
33
GLOSSARY.md
Normal file
33
GLOSSARY.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Glossary
|
||||
|
||||
Terms and abbreviations used throughout the homelab wiki.
|
||||
|
||||
| Term | Meaning |
|
||||
|------|---------|
|
||||
| **Authentik** | SSO/identity provider. Core runs on the VPS; forward-auth outpost at LXC 106 on hubris |
|
||||
| **Caddy** | Reverse proxy (LXC 121). Terminates TLS for every `*.hubris.network` hostname |
|
||||
| **Caveman** | Terse communication standard for agent responses — no filler, keep substance |
|
||||
| **Forward-auth** | Caddy snippet that delegates authentication to an Authentik outpost. Protects web UIs like qBit, SABnzbd |
|
||||
| **Gitea** | Git server at `git.hubris.network`. Hosts all tracked config repos |
|
||||
| **Gluetun** | WireGuard VPN sidecar on arriman. All \*arr traffic routes through it |
|
||||
| **HAOS** | Home Assistant Operating System. VM 108 on hubris |
|
||||
| **Hubris** | Primary Proxmox VE node (GMKtec NucBox M6 Ultra). PVE hostname, cluster member 1 |
|
||||
| **LXC** | Linux Container (Proxmox). VM-like isolation without a full OS kernel |
|
||||
| **LVM-thin** | Thin-provisioned logical volume manager. Used for all container/VM storage |
|
||||
| **MCP** | Model Context Protocol (MCP server at `mcp.hubris.network`). Structured tools for agents to query homelab state |
|
||||
| **Mesh** | Overlay VPN for off-LAN connectivity. Netbird is current; Tailscale is legacy |
|
||||
| **Netbird** | Preferred mesh VPN. VPS hosts the management plane; all homelab nodes are members |
|
||||
| **OIDC** | OpenID Connect. Protocol used by Authentik for SSO login flows |
|
||||
| **Oikos** | Agent operating model (OIKOS.md). OODA loop, risk classes, policy, ontology |
|
||||
| **PVE** | Proxmox Virtual Environment — the hypervisor on both hubris and strong |
|
||||
| **SOPS** | `sops` — Mozilla SOPS. Encrypts secrets with age keys so they live in the git repo |
|
||||
| **Strong** | Secondary Proxmox VE node. Cluster member 2 (hostname `strong`, nickname ludo/ludo-mini) |
|
||||
| **Traefik** | Reverse proxy on IONOS VPS. Serves `*.hubris.network` to the public internet |
|
||||
| **VAAPI** | Video Acceleration API. Intel/AMD GPU-based hardware transcode for Jellyfin |
|
||||
| **VPS** | Virtual Private Server at IONOS (`82.165.190.79`). Runs Authentik core + Netbird management |
|
||||
| **\\*arr** | Media automation suite: Sonarr (TV), Radarr (movies), Lidarr (music), Prowlarr (indexer), Bazarr (subtitles), Readarr (books — not in use) |
|
||||
|
||||
## See also
|
||||
|
||||
- [Infrastructure index](infrastructure/index.md) — cross-cutting systems each with their own doc page
|
||||
- [OIKOS operating model](OIKOS.md) — agent policy, risk classes, lifecycle
|
||||
53
README.md
53
README.md
@@ -2,39 +2,47 @@
|
||||
|
||||
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**.
|
||||
> Last refreshed against live state: **2026-07-06**.
|
||||
|
||||
## Quick navigation
|
||||
|
||||
- [Proxmox hosts](#proxmox-hosts) — hubris (primary) + strong (cluster member)
|
||||
- [VMs](#vms) — ZimaOS, Home Assistant
|
||||
- [LXC containers](#lxc-containers) — service fleet (17 containers)
|
||||
- [Cross-cutting infrastructure](#cross-cutting-infrastructure) — DNS, ingress, mesh, storage, auth
|
||||
- [Investigations](#investigations) — incident timelines
|
||||
- [Operations](#operations) — cheatsheet, enrollment, runbooks
|
||||
- [Glossary](GLOSSARY.md) — term definitions
|
||||
- [Conventions](#conventions) — wiki style, changelog hygiene, same-session update rule
|
||||
|
||||
## Map
|
||||
|
||||
### Hosts
|
||||
- [`hubris`](hosts/hubris.md) — Proxmox VE node, GMKtec NucBox M6 Ultra, `192.168.8.77` — runs everything today
|
||||
- [`strong`](hosts/strong.md) — Proxmox VE node (cluster hostname `strong`), `192.168.178.181` — 2nd member of the `Homelab` cluster as of 2026-07-01, hosts no guests yet
|
||||
### Proxmox hosts
|
||||
- [`hubris`](hosts/hubris.md) — PVE node, GMKtec NucBox M6 Ultra, `192.168.8.77` — primary host, runs [8 LXCs](containers/index.md) + 2 VMs
|
||||
- [`strong`](hosts/strong.md) — PVE node (cluster hostname `strong`), `192.168.178.181` — 2nd member of `Homelab` cluster. Hosts [7 LXCs](containers/index.md) migrated from hubris (Phase 1+2, 2026-07-05)
|
||||
|
||||
### VMs
|
||||
- [100 — `zimaos`](vms/100-zimaos.md) — ZimaOS 1.6.1, NAS frontend (evaluation)
|
||||
- [108 — `haos-16.3`](vms/108-haos.md) — Home Assistant OS
|
||||
- See [vms/index.md](vms/index.md) for the full table
|
||||
|
||||
### LXC containers
|
||||
See the full table in [`containers/index.md`](containers/index.md). Quick links:
|
||||
See the full table with IPs, hosts, mounts, and status in
|
||||
[`containers/index.md`](containers/index.md). Quick summary:
|
||||
|
||||
| ID | Name | IP | Role |
|
||||
| --- | ---------------- | --------------- | --------------------------------------------- |
|
||||
| 101 | [jellyfin](containers/101-jellyfin.md) | 192.168.8.206 | Media server |
|
||||
| 102 | [nfs-export](containers/102-nfs-export.md) | 192.168.8.200 | NFSv4 re-export of /mnt/library for ZimaOS |
|
||||
| 103 | [paperless](containers/103-paperless.md) | 192.168.8.130 | Document mgmt |
|
||||
| 104 | [gitea](containers/104-gitea.md) | 192.168.8.121 | Git server |
|
||||
| 105 | [apps](containers/105-apps.md) | 192.168.8.205 | Docker host (Artifacto / PlantUML / Portainer / WriteFreely) |
|
||||
| 114 | [nextcloud](containers/114-nextcloud.md) | 192.168.8.224 | Personal cloud |
|
||||
| 118 | [elementsynapse](containers/118-elementsynapse.md) | 192.168.8.239 | Matrix Synapse |
|
||||
| 119 | [sophia](containers/119-sophia.md) | 192.168.8.157 | Sophia |
|
||||
| 120 | [mule-images](containers/120-mule-images.md) | 192.168.8.136 | Mule-image / mulita photos |
|
||||
| 121 | [caddy](containers/121-caddy.md) | 192.168.8.175 | Reverse proxy |
|
||||
| 122 | [arriman](containers/122-arriman.md) | 192.168.8.132 | Docker host (\*arr stack) |
|
||||
| 124 | [authentik](containers/124-authentik.md) | 192.168.8.180 | SSO + split-horizon DNS |
|
||||
| 130 | [grimmory](containers/130-grimmory.md) | 192.168.8.213 | Digital library (Grimmory — fork of Booklore) |
|
||||
| 132 | [rclone](containers/132-rclone.md) | 192.168.8.214 | Off-host backup → Proton Drive (rclone + Web GUI) |
|
||||
- **hubris** (10 active): 102 nfs-export, 103 paperless, 104 gitea, 105 apps,
|
||||
114 nextcloud, 119 sophia, 120 mule-images, 121 caddy, 124 authentik (outpost),
|
||||
128 trmnl, 132 rclone
|
||||
- **strong** (7 active): 101 jellyfin, 118 elementsynapse, 122 arriman,
|
||||
129 house, 130 grimmory, 133 seanime, 134 romm
|
||||
- **Destroyed (archaeology)**: 100 arr, 106 flaresolverr, 107 marimo,
|
||||
109 syncthing, 110 photoprism, 111 karakeep, 112 immich, 115 reticulum,
|
||||
123 claudio-bot, 125 seafile, 126 plato, 127 mule-photos-new — see
|
||||
[containers/index.md](containers/index.md#recently-destroyed-kept-for-archaeology)
|
||||
|
||||
### Cross-cutting infrastructure
|
||||
- [Infrastructure index](infrastructure/index.md) — map of every cross-cutting system
|
||||
- [Glossary](GLOSSARY.md) — term definitions
|
||||
- [DNS — split-horizon](infrastructure/dns.md)
|
||||
- [Ingress — Caddy + VPS traefik](infrastructure/ingress.md)
|
||||
- [Mesh — Tailscale → Netbird migration](infrastructure/mesh.md)
|
||||
@@ -47,7 +55,8 @@ See the full table in [`containers/index.md`](containers/index.md). Quick links:
|
||||
- [Homelab context distribution](infrastructure/homelab-context.md) — cross-client `/opt/homelab-context` + MCP + secrets-issuance
|
||||
|
||||
### Investigations
|
||||
Time-stamped incident notes / experiments in [`investigations/`](investigations/index.md).
|
||||
Time-stamped incident notes / experiments in [`investigations/index.md`](investigations/index.md).
|
||||
Resolved cases move to [`investigations/archive/`](investigations/archive/).
|
||||
|
||||
### Operations
|
||||
- [Command cheatsheet](operations/commands.md)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# 101 — `jellyfin`
|
||||
|
||||
Media server: serves the movies / TV / anime / music libraries from `/mnt/library` to LAN clients. Hardware transcoding via AMD Radeon 760M VAAPI. Authentik SSO via OIDC.
|
||||
Media server: serves the movies / TV / anime / music libraries from `/mnt/media_local` to LAN clients. Hardware transcoding via AMD Radeon 680M + RX 7600 VAAPI. Authentik SSO via OIDC.
|
||||
|
||||
## At a glance
|
||||
- **Hostname:** `jellyfin`
|
||||
- **IP:** `192.168.8.206`
|
||||
- **Privilege:** **unprivileged** + idmap (so it can write to the `media` group on `/mnt/library`)
|
||||
- **Host:** **strong** (migrated from hubris 2026-07-05)
|
||||
- **IP:** `192.168.8.246`
|
||||
- **Privilege:** privileged (recreated on strong as priv)
|
||||
- **Resources:** 4 cores / 8 GiB RAM / 1 GiB swap / 16 GiB rootfs
|
||||
- **GPU:** `/dev/dri/renderD128` (AMD Radeon 760M, RDNA 3) passed via `dev0` in LXC config
|
||||
- **Mounts:** `/mnt/library` ↔ `/mnt/library`
|
||||
- **GPU:** `/dev/dri/renderD128` + `/dev/dri/card0` (AMD Radeon 680M iGPU + RX 7600 dGPU) passed via `dev0` / `dev1` in LXC config
|
||||
- **Mounts:** `/mnt/media_local` ↔ `/mnt/library`
|
||||
- **Public hostname:** [`media.hubris.network`](../infrastructure/dns.md) → [caddy](121-caddy.md) → `:8096`
|
||||
- **Version:** Jellyfin 10.11.11 (apt package, Ubuntu 24.04 noble repo)
|
||||
- **FFmpeg:** jellyfin-ffmpeg7 7.1.4
|
||||
@@ -21,10 +21,16 @@ Media server: serves the movies / TV / anime / music libraries from `/mnt/librar
|
||||
|
||||
## Hardware acceleration (VAAPI)
|
||||
|
||||
GPU is passed through to the LXC via `dev0: /dev/dri/renderD128,gid=993` in
|
||||
`/etc/pve/lxc/101.conf`. The `jellyfin` user is in the `render` (GID 993) and
|
||||
GPU is passed through to the LXC via `dev0: /dev/dri/renderD128,gid=993` and
|
||||
`dev1: /dev/dri/card0,gid=44` in
|
||||
`/etc/pve/lxc/101.conf` (strong). The `jellyfin` user is in the `render` (GID 993) and
|
||||
`video` groups inside the container.
|
||||
|
||||
| GPU | Model | Role |
|
||||
|-----|-------|------|
|
||||
| Radeon 680M | iGPU (AMD Ryzen 7 PRO 6850U) | Primary VAAPI encoder/decoder |
|
||||
| RX 7600 | dGPU (add-in) | Secondary transcode, HEVC/AV1 encoding |
|
||||
|
||||
Encoding settings (`/etc/jellyfin/encoding.xml`):
|
||||
- `HardwareAccelerationType`: `vaapi`
|
||||
- `VaapiDevice`: `/dev/dri/renderD128`
|
||||
@@ -120,7 +126,7 @@ User → media.hubris.network → Caddy (TLS, no forward-auth) → Jellyfin :809
|
||||
```
|
||||
|
||||
## Permissions
|
||||
Member of the [media GID 10000](../infrastructure/media-permissions.md) standard. Service user `jellyfin` is in the `media` group inside the container; idmap block in `/etc/pve/lxc/101.conf` maps in-container GID 10000 to host GID 10000.
|
||||
Member of the [media GID 10000](../infrastructure/media-permissions.md) standard. Service user `jellyfin` is in the `media` group inside the container; `/mnt/media_local` on strong's ludo-lvm is owned `root:media` with mode `2775`.
|
||||
|
||||
## Related
|
||||
- [Caddy reverse proxy](121-caddy.md)
|
||||
@@ -131,6 +137,9 @@ Member of the [media GID 10000](../infrastructure/media-permissions.md) standard
|
||||
|
||||
## Changelog
|
||||
|
||||
### 2026-07-06 — wiki: IP, host, GPU, mount path updated for strong migration
|
||||
Updated At-a-glance: IP 206→246, host hubris→strong, mount /mnt/library→/mnt/media_local, GPU Radeon 760M→680M+RX7600, privilege unpriv→priv. Permissions section updated. Changelog entry in 122-arriman.md updated similarly.
|
||||
|
||||
### 2026-07-04 — VAAPI hardware acceleration + Authentik SSO + resource bump
|
||||
- Upgraded Jellyfin 10.11.8 → 10.11.11 (purge + reinstall to fix DB migration bug)
|
||||
- Enabled VAAPI hardware acceleration (Radeon 760M): h264/hevc/vc1/vp9/av1 decode + encode
|
||||
|
||||
@@ -4,7 +4,8 @@ Matrix homeserver (Synapse). Backs `@dtoro:avispero`.
|
||||
|
||||
## At a glance
|
||||
- **Hostname:** `elementsynapse`
|
||||
- **IP:** `192.168.8.239`
|
||||
- **IP:** `192.168.8.242`
|
||||
- **Host:** **strong** (migrated from hubris 2026-07-05)
|
||||
- **Privilege:** **unprivileged**
|
||||
- **Resources:** 1 core / 2 GiB RAM / **16 GiB rootfs** (grown from 8 GiB on 2026-05-15 after disk-full incident)
|
||||
- **Mounts:** none from `/mnt/library`
|
||||
|
||||
@@ -11,16 +11,16 @@ The reverse proxy. Terminates TLS for every `*.hubris.network` hostname on the L
|
||||
- **Config:** `/etc/caddy/Caddyfile` is a [git checkout of `dtoro/caddy-conf`](#auto-deploy)
|
||||
- **Cert source:** Let's Encrypt **DNS-01** via IONOS API (`IONOS_AUTH_API_TOKEN`).
|
||||
|
||||
## Sites currently served (live as of 2026-04-28)
|
||||
## Sites currently served (live as of 2026-07-06)
|
||||
|
||||
- `artifacto.hubris.network` → [apps (105)](105-apps.md) `:3100`
|
||||
- `auth.hubris.network` → [authentik (124)](124-authentik.md) `:9000`
|
||||
- `blog.hubris.network` → [apps (105)](105-apps.md) `:8080`
|
||||
- `books.hubris.network` → [apps (105)](105-apps.md) `:6060`
|
||||
- `books.hubris.network` → [grimmory (130)](130-grimmory.md) `:6060`
|
||||
- `cloud.hubris.network` → [nextcloud (114)](114-nextcloud.md) `:443`
|
||||
- `docker.hubris.network` → [apps (105)](105-apps.md) `:9443`
|
||||
- `git.hubris.network` → [gitea (104)](104-gitea.md) `:3000` (+ `handle_path /_plantuml/*` → apps `:8079`)
|
||||
- `home.hubris.network` → [haos VM (108)](../vms/108-haos.md) `192.168.8.101:8123`
|
||||
- `house.hubris.network` → [house (129)](129-house.md) `:3000`
|
||||
- `jellyseerr.hubris.network` → [arriman (122)](122-arriman.md) `:5056`
|
||||
- `matrix.hubris.network` → [elementsynapse (118)](118-elementsynapse.md) `:8008`
|
||||
- `media.hubris.network` → [jellyfin (101)](101-jellyfin.md) `:8096`
|
||||
@@ -28,7 +28,10 @@ The reverse proxy. Terminates TLS for every `*.hubris.network` hostname on the L
|
||||
- `photos.hubris.network` → [mule-images (120)](120-mule-images.md) `:3000`
|
||||
- `proxmox.hubris.network` → [hubris host](../hosts/hubris.md) `:8006`
|
||||
- `qbit.hubris.network` → [arriman (122)](122-arriman.md) `:8080`
|
||||
- `roms.hubris.network` → [romm (134)](134-romm.md) `:80`
|
||||
- `sab.hubris.network` → [arriman (122)](122-arriman.md) `:8082` (Authentik forward-auth)
|
||||
- `teddy.hubris.network` → LXC 131 `192.168.8.150:8443`
|
||||
- `trmnl.hubris.network` → [trmnl (128)](128-trmnl.md) `:9851`
|
||||
|
||||
> **Reminder:** Caddy alone isn't enough to make a new subdomain reachable on the LAN. Each one needs an entry in [DNS split-horizon](../infrastructure/dns.md) too.
|
||||
|
||||
|
||||
@@ -4,10 +4,11 @@ Docker host running the \*arr stack via [`ezarr`](https://github.com/ezarr/ezarr
|
||||
|
||||
## At a glance
|
||||
- **Hostname:** `arriman`
|
||||
- **IP:** `192.168.8.132`
|
||||
- **IP:** `192.168.8.245`
|
||||
- **Host:** **strong** (migrated from hubris 2026-07-05)
|
||||
- **Privilege:** privileged
|
||||
- **Resources:** 4 cores / 8 GiB RAM / 24 GiB rootfs
|
||||
- **Mounts:** `/mnt/library` ↔ `/mnt/library`
|
||||
- **Mounts:** `/mnt/media_local` ↔ `/mnt/library`
|
||||
- **Public hostnames:** `jellyseerr` / `qbit` / `sab` (see below)
|
||||
|
||||
## Compose
|
||||
|
||||
@@ -5,7 +5,8 @@ Yuvomi family planner (formerly Oikos). Self-hosted family planner with 14 modul
|
||||
## At a glance
|
||||
|
||||
- **Hostname:** `house`
|
||||
- **IP:** `192.168.8.212` (static)
|
||||
- **IP:** `192.168.8.244`
|
||||
- **Host:** **strong** (migrated from hubris 2026-07-05)
|
||||
- **Privilege:** unprivileged
|
||||
- **Resources:** 1 core / 1344 MiB RAM / 8 GiB rootfs (Debian 13)
|
||||
- **Mounts:** none
|
||||
|
||||
@@ -5,17 +5,18 @@ Self-hosted digital library (eBooks, comics, audiobooks). Community fork/success
|
||||
## At a glance
|
||||
|
||||
- **Hostname:** `grimmory`
|
||||
- **IP:** `192.168.8.213` (static, set in PVE `net0` config — same pattern as all other LXCs)
|
||||
- **IP:** `192.168.8.247`
|
||||
- **Host:** **strong** (migrated from hubris 2026-07-05)
|
||||
- **Privilege:** privileged (UID = host UID for `/mnt/library` media GID)
|
||||
- **Resources:** 1 core / 2 GiB RAM / 16 GiB rootfs (Debian 13)
|
||||
- **Mounts:** `/mnt/library`
|
||||
- **Mounts:** `/mnt/media_local` ↔ `/mnt/library`
|
||||
- **Public hostname:** `books.hubris.network`
|
||||
|
||||
## Service / port map
|
||||
|
||||
| Service | Listen | Notes |
|
||||
|---------|--------|-------|
|
||||
| Grimmory | `192.168.8.213:6060` | Docker Compose at `/opt/grimmory/` |
|
||||
| Grimmory | `192.168.8.247:6060` | Docker Compose at `/opt/grimmory/` |
|
||||
| MariaDB | internal only | Sidecar in the same compose stack |
|
||||
|
||||
## Compose
|
||||
@@ -43,7 +44,7 @@ Uses Confidential client (client secret stored in Grimmory's DB — migrated fro
|
||||
- **Client type:** Confidential (client secret in `oidc_provider_details` in MariaDB `app_settings`)
|
||||
- **Redirect URI:** `https://books.hubris.network/oauth2-callback`
|
||||
- **Scopes:** openid, profile, email, offline_access
|
||||
- **Back-channel logout:** `http://192.168.8.213:6060/api/v1/auth/oidc/backchannel-logout`
|
||||
- **Back-channel logout:** `http://192.168.8.247:6060/api/v1/auth/oidc/backchannel-logout`
|
||||
- **Application slug:** `booklore` → Issuer URI: `https://auth.hubris.network/application/o/booklore/`
|
||||
|
||||
## Media permissions
|
||||
@@ -53,7 +54,7 @@ LXC is privileged → in-container UID = host UID. Docker container gets media G
|
||||
## Related
|
||||
|
||||
- [apps (105)](105-apps.md) — previous host (Booklore)
|
||||
- [Caddy (121)](121-caddy.md) — `books.hubris.network → 192.168.8.213:6060`
|
||||
- [Caddy (121)](121-caddy.md) — `books.hubris.network → 192.168.8.247:6060`
|
||||
- [Authentik (124)](124-authentik.md) — OIDC provider `Grimmory`
|
||||
- [DNS (107)](107-dns.md) — `books.hubris.network → 192.168.8.175` (unchanged from Booklore)
|
||||
- [Media permissions](../infrastructure/media-permissions.md)
|
||||
|
||||
@@ -31,7 +31,7 @@ Most containers live on [`hubris`](../hosts/hubris.md). Some have been
|
||||
| 106 | flaresolverr | ~2026-04-28 | Folded into the arriman docker compose |
|
||||
| 116 | heaper | 2026-05-14 | Decommissioned by user; data subtree at `/mnt/library/heaper` (224 MiB) retained |
|
||||
| 126 | plato | 2026-06-28 | Notes/discovery workspace decommissioned; data at `/mnt/library/documents/plato` retained for archaeology |
|
||||
| 123 | claudio-bot | 2026-06-04 | Replaced by Hermes Agent on mac-mini; monitoring migrated to `homelab-health-watchdog` cron. See [deprecation plan](../plans/2026-06-04_130000-deprecate-claudio-bot.md) |
|
||||
| 123 | claudio-bot (destroyed — see [archive](archive/123-claudio-bot.md)) | 2026-06-04 | Replaced by Hermes Agent on mac-mini; monitoring migrated to `homelab-health-watchdog` cron. See [deprecation plan](../plans/2026-06-04_130000-deprecate-claudio-bot.md) |
|
||||
| 109 | syncthing | 2026-05-14 | Decommissioned by user; `/mnt/library/syncthing` was already empty |
|
||||
| 125 | seafile | 2026-05-13 | Seafile Pro evaluation, user disliked the product; teardown also removed `files.hubris.network` from caddy + dnsmasq |
|
||||
| 107 | marimo | between 2026-04-21 and 2026-04-28 | Decommissioned |
|
||||
|
||||
@@ -6,7 +6,7 @@ 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`)
|
||||
- **Role:** Proxmox VE 9.2.3 cluster member (kernel `7.0.12-1-pve`) — hosts [7 LXCs](../containers/index.md) migrated from hubris (Phase 1+2, 2026-07-05)
|
||||
- **Naming:** the OS/cluster hostname is `strong` (leftover from install,
|
||||
kept as-is). This wiki page and `inventory.yaml` also use `strong` as of
|
||||
2026-07-01 — earlier the same day the inventory entry was briefly named
|
||||
|
||||
66
infrastructure/index.md
Normal file
66
infrastructure/index.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# Infrastructure — cross-cutting systems
|
||||
|
||||
The homelab's shared infrastructure: systems that span multiple nodes and
|
||||
are documented in their own pages. Each system below links to its full doc.
|
||||
|
||||
## Network
|
||||
|
||||
- **[Network](network.md)** — physical topology, subnets, routing, DHCP.
|
||||
Homelab `192.168.8.0/24` isolated from household `192.168.178.0/24`.
|
||||
Proxmox hubris acts as subnet router.
|
||||
- **[DNS — split-horizon](dns.md)** — Technitium DNS on LXC 107,
|
||||
`192.168.8.2:53`. `*.hubris.network` resolves to LAN IPs on the homelab
|
||||
network and to mesh addresses off-LAN.
|
||||
|
||||
## Connectivity / mesh
|
||||
|
||||
- **[Mesh — Tailscale → Netbird migration](mesh.md)** — overlay networking.
|
||||
Netbird is the preferred path; Tailscale is legacy.
|
||||
- **[SSH access](ssh-access.md)** — dual-server SSH (OpenSSH + Netbird SSH)
|
||||
on hubris, key distribution.
|
||||
|
||||
## Public ingress
|
||||
|
||||
- **[Public ingress — VPS traefik + cert mirror](ingress.md)** — how home
|
||||
services reach the open internet. Two-stage: VPS traefik (IONOS) terminates
|
||||
TLS, proxies over Netbird to home Caddy.
|
||||
- **[Caddy reverse proxy](../containers/121-caddy.md)** — LAN endpoint.
|
||||
Terminates TLS for every `*.hubris.network` hostname, forwards to backends.
|
||||
|
||||
## Storage
|
||||
|
||||
- **[Media permissions — GID 10000 standard](media-permissions.md)** — shared
|
||||
group permission model across all LXCs that read/write the media library.
|
||||
- **[Backups — rclone → Proton Drive](backups.md)** — off-host backup strategy.
|
||||
LXC 132 handles rclone to Proton Drive; restic-on-USB deprecated.
|
||||
|
||||
## Identity & access
|
||||
|
||||
- **[Authentik SSO](../containers/124-authentik.md)** — identity provider.
|
||||
Core server runs on the VPS; LAN forward-auth outpost at LXC 106.
|
||||
OIDC providers configured for Jellyfin, Jellyseerr, Sabnzbd, qBittorrent,
|
||||
Yuvomi, and more.
|
||||
|
||||
## Management & automation
|
||||
|
||||
- **[Homelab context distribution](homelab-context.md)** — `/opt/homelab-context`
|
||||
clone, MCP server, secrets issuance, cross-client sync.
|
||||
- **[Auto-deploy — gitea-webhook pipelines](auto-deploy.md)** — push-to-deploy
|
||||
for Caddy config, mule-image, and other tracked repos.
|
||||
- **[Monitoring](monitoring.md)** — health checks, watchdogs, alerting
|
||||
(migrated from claudio-bot to Hermes cron).
|
||||
- **[VPS hardening](vps-hardening.md)** — IONOS netbird VPS: fail2ban,
|
||||
nftables, OIDC SSH, security posture.
|
||||
|
||||
## Topology
|
||||
|
||||
- **[Topology diagram (generated)](topology.md)** — Mermaid graph of compute,
|
||||
ingress routing, and storage mounts. Auto-generated from `inventory.yaml`
|
||||
by `oikos/gen-topology.py`.
|
||||
|
||||
## Related
|
||||
|
||||
- [README](../README.md) — entry point
|
||||
- [Containers index](../containers/index.md)
|
||||
- [Operations cheatsheet](../operations/commands.md)
|
||||
- [OIKOS operating model](../OIKOS.md)
|
||||
@@ -2,14 +2,23 @@
|
||||
|
||||
Time-stamped incident reports and experiments. One entry per incident; the entry is the canonical source. Per-node changelog entries link back here.
|
||||
|
||||
## Index
|
||||
## Active / recent
|
||||
|
||||
| Date | Title | Status |
|
||||
| ------------ | ------------------------------------------------------------------ | ------------- |
|
||||
|| 2026-06-06 | [Frequent Authentik login prompts — session lifetime fix](2026-06-06-authentik-session-lifetime.md) | Resolved — `session_duration=days=30`, `SESSION_COOKIE_AGE=30d` |
|
||||
|| 2026-05-31 | [Authentik migrated from LXC 124 to the VPS](2026-05-31-authentik-vps-migration.md) | Resolved; LXC 124 Authentik in ~2-week dual-run before decommission |
|
||||
| 2026-06-06 | [Caddyfile truncation incident](2026-06-06-caddyfile-truncation.md) | Resolved — permanent safeguards deployed (site-count guard, auto-stash, auto-backup) |
|
||||
| 2026-06-06 | [Frequent Authentik login prompts — session lifetime fix](2026-06-06-authentik-session-lifetime.md) | Resolved — `session_duration=days=30`, `SESSION_COOKIE_AGE=30d` |
|
||||
| 2026-06-03 | [Moonlight/Sunshine streaming — WiFi jitter](2026-06-03-moonlight-sunshine-wifi-jitter.md) | Mitigations applied; definitive fix requires wiring mac-mini via Ethernet |
|
||||
| 2026-04-21 | [Hubris crash loop — thermal + USB drive](2026-04-21-hubris-crash-loop.md) | Drive removal A/B test passing as of 2026-04-28 (3+ days uptime) |
|
||||
| 2026-06-01 | [Mac-mini onboarding](2026-06-01-mac-mini-onboarding.md) | Onboarded |
|
||||
|
||||
## Resolved (archived)
|
||||
|
||||
See [`archive/`](archive/):
|
||||
|
||||
| Date | Title |
|
||||
| ------------ | ------------------------------------------------------------------ |
|
||||
| 2026-04-21 | [Hubris crash loop — thermal + USB drive](archive/2026-04-21-hubris-crash-loop.md) |
|
||||
| 2026-05-31 | [Authentik migrated from LXC 124 to the VPS](archive/2026-05-31-authentik-vps-migration.md) |
|
||||
|
||||
## Conventions
|
||||
|
||||
@@ -17,3 +26,4 @@ Time-stamped incident reports and experiments. One entry per incident; the entry
|
||||
- Mandatory sections: Summary, Timeline, Root cause, Mitigations applied, Open questions.
|
||||
- Update the entry as the situation evolves; never rewrite history. Add new dated sections at the bottom.
|
||||
- Link back from every node's changelog that's affected.
|
||||
- Move to `archive/` when the incident is fully resolved and no longer actively referenced.
|
||||
@@ -1,19 +1,29 @@
|
||||
# Plans
|
||||
|
||||
Pre-flight runbooks for planned changes that haven't happened yet. Once executed, move the outcome to `investigations/` (if anything interesting happened) or just a changelog entry on the affected node pages.
|
||||
Pre-flight runbooks for planned changes. When a plan is executed, move it to
|
||||
[`done/`](done/) and add changelog entries on affected node pages. If things
|
||||
went sideways, open an investigation.
|
||||
|
||||
## Index
|
||||
## Active
|
||||
|
||||
| Date | Title | Status |
|
||||
| ---- | ----- | ------ |
|
||||
| 2026-06-24 | [TRMNL plugins LXC (128) + middleware deploy pipeline](2026-06-24-trmnl-plugins-lxc.md) | In Progress |
|
||||
| 2026-06-25 | [Yuvomi deployment — house.hubris.network](2026-06-25-yuvomi-deployment.md) | Done |
|
||||
| 2026-06-24 | [TRMNL plugins LXC (128) + middleware deploy pipeline](2026-06-24-trmnl-plugins-lxc.md) | In Progress |
|
||||
| 2026-06-01 | [Slate AX → SODOLA managed switch migration](2026-06-01-slate-ax-to-sodola-migration.md) | Done |
|
||||
|
||||
## Done
|
||||
|
||||
See [`done/`](done/) for executed plans:
|
||||
|
||||
| Date | Title |
|
||||
| ---- | ----- |
|
||||
| 2026-06-01 | [Slate AX → SODOLA managed switch migration](done/2026-06-01-slate-ax-to-sodola-migration.md) |
|
||||
| 2026-06-04 | [Deprecate claudio-bot](done/2026-06-04_130000-deprecate-claudio-bot.md) |
|
||||
| 2026-06-25 | [Yuvomi deployment — house.hubris.network](done/2026-06-25-yuvomi-deployment.md) |
|
||||
| 2026-06-29 | [Grimmory migration — Booklore → dedicated LXC](done/2026-06-29-grimmory-migration.md) |
|
||||
|
||||
## Conventions
|
||||
|
||||
- File name: `YYYY-MM-DD-<slug>.md`. Use the *target* date if known, otherwise the planning date.
|
||||
- Status: `Planned` → `In Progress` → `Done` (update index entry as it moves).
|
||||
- When done: add a changelog entry on every affected node page, then update status to `Done` here. If things went sideways, open an investigation.
|
||||
- Plans are append-only once execution starts — don't rewrite pre-flight intent after the fact.
|
||||
- Status: `Planned` → `In Progress` → `Done` (move to `done/` on completion).
|
||||
- When done: add a changelog entry on every affected node page, then move the file to `done/`.
|
||||
- Plans are append-only once execution starts — don't rewrite pre-flight intent after the fact.
|
||||
@@ -1,3 +1,10 @@
|
||||
---
|
||||
name: budget-import-from-csv
|
||||
risk_class: config_mutation
|
||||
inputs: [csv_file]
|
||||
references: [containers/129-house.md]
|
||||
---
|
||||
|
||||
# Runbook: Budget import from N26 CSV → Yuvomi
|
||||
|
||||
Distil a bank-export CSV into Yuvomi's Budget and Subscriptions modules using
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: recover-dpkg-interrupted
|
||||
risk_class: reversible_low
|
||||
verification: "dpkg --audit (should be clean); apt-get check"
|
||||
---
|
||||
|
||||
# Runbook — recover from dpkg-interrupted state
|
||||
|
||||
You're here because an apt run got killed mid-transaction and the target now
|
||||
14
vms/index.md
Normal file
14
vms/index.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# VMs — index
|
||||
|
||||
Two QEMU VMs running on [hubris](../hosts/hubris.md):
|
||||
|
||||
| ID | Name | Role | IP | Public hostname |
|
||||
|----|------|------|----|-----------------|
|
||||
| 100 | [zimaos](100-zimaos.md) | NAS frontend eval (ZimaOS) | `192.168.8.195` | [`zimaos.hubris.network`](../infrastructure/dns.md) |
|
||||
| 108 | [haos-16.3](108-haos.md) | Home automation (HAOS) | `192.168.8.101` | [`home.hubris.network`](../infrastructure/dns.md) |
|
||||
|
||||
## Related
|
||||
|
||||
- [Hubris host](../hosts/hubris.md) — both VMs run here
|
||||
- [Containers index](../containers/index.md) — LXCs on both nodes
|
||||
- [README](../README.md)
|
||||
Reference in New Issue
Block a user