homelab-architecture: add Mermaid topology / auth / MCP / data plane diagrams
This commit is contained in:
@@ -378,3 +378,135 @@ must target *exactly these silent-failure classes*.
|
|||||||
`/mnt/pve/unas` (catches a regression of the tier-1 rule).
|
`/mnt/pve/unas` (catches a regression of the tier-1 rule).
|
||||||
4. Container unhealthy/restart-looping > 5 m (the gluetun pattern).
|
4. Container unhealthy/restart-looping > 5 m (the gluetun pattern).
|
||||||
5. local-zfs `rpool` or NFS pool > 85 %; 6. TLS cert < 14 d.
|
5. local-zfs `rpool` or NFS pool > 85 %; 6. TLS cert < 14 d.
|
||||||
|
|
||||||
|
## Topology — at a glance
|
||||||
|
|
||||||
|
### Physical / CT layout
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TB
|
||||||
|
subgraph Host["Proxmox host · 192.168.1.20 · Intel Core Ultra 7 155H · 64 GiB"]
|
||||||
|
direction TB
|
||||||
|
haos["VM 100 · haos<br/>(.60)<br/>Home Assistant"]
|
||||||
|
shepard["CT 101 · shepard<br/>(.49)<br/>Shepard product stack"]
|
||||||
|
dns["CT 102 · dns<br/>(.2)<br/>AdGuard Home"]
|
||||||
|
backrest["CT 103 · backrest<br/>(.3)<br/>Backrest / restic"]
|
||||||
|
docker104["<b>CT 104 · docker</b><br/>(.40) · 16c/48G/200G<br/>~65 containers · Intel Arc passthrough"]
|
||||||
|
nc["CT 105 · nextcloud<br/>(.41)<br/>Nextcloud AIO (CIFS to UNAS)"]
|
||||||
|
zoraxy["CT 108 · zoraxy<br/>(.4)<br/>reverse proxy + ACME"]
|
||||||
|
obs(["CT 109 · observe<br/>(.6) · <i>planned</i><br/>Prom / Graf / Arcane / Homarr / Tinyauth"])
|
||||||
|
id["CT 110 · id<br/>(.5)<br/>Pocket-ID (moved here 2026-05-20)"]
|
||||||
|
dev["CT 111 · dev<br/>(.42) · 12c/32G/60G<br/>Coder + Gitea + workspaces · Intel Arc"]
|
||||||
|
db(["CT 113 · db<br/>(.?) · <i>planned</i><br/>shared Postgres + pgbouncer"])
|
||||||
|
end
|
||||||
|
UNAS[("UNAS<br/>192.168.1.31<br/>NFSv3 + CIFS")]
|
||||||
|
UDM[["UDM-SE · 192.168.1.1<br/>UniFi gateway · DNS → AdGuard"]]
|
||||||
|
Inet([Internet · ACME challenges · jottacloud · LiteLLM upstreams])
|
||||||
|
|
||||||
|
UDM <--> Host
|
||||||
|
UDM <--> Inet
|
||||||
|
UNAS <--> shepard
|
||||||
|
UNAS <--> backrest
|
||||||
|
UNAS <--> docker104
|
||||||
|
UNAS <--> nc
|
||||||
|
UNAS <--> dev
|
||||||
|
|
||||||
|
classDef planned stroke-dasharray:5 5,fill:#222,stroke:#aaa,color:#aaa
|
||||||
|
class obs,db planned
|
||||||
|
```
|
||||||
|
|
||||||
|
### Auth plane — Pocket-ID is the universal IdP
|
||||||
|
|
||||||
|
Every web service that supports OIDC federates against Pocket-ID. Coder/Gitea/Vaultwarden access through Zoraxy; Zoraxy + Tinyauth fronts the non-OIDC-native ones.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
user(["fkrebs · browser / VS Code / Claude"]) --> zx[Zoraxy<br/>CT 108]
|
||||||
|
zx --> coder[Coder · CT 111]
|
||||||
|
zx --> gitea[Gitea · CT 111]
|
||||||
|
zx --> nc2[Nextcloud · CT 105]
|
||||||
|
zx --> immich[Immich · CT 104]
|
||||||
|
zx --> lobe[LobeChat · CT 104]
|
||||||
|
zx --> n8n[n8n · CT 104]
|
||||||
|
zx --> mcp[MCP gateway · CT 104]
|
||||||
|
zx --> vw[Vaultwarden · CT 104]
|
||||||
|
coder --> pid[(Pocket-ID<br/>CT 110)]
|
||||||
|
gitea --> pid
|
||||||
|
nc2 --> pid
|
||||||
|
immich --> pid
|
||||||
|
lobe --> pid
|
||||||
|
n8n --> pid
|
||||||
|
mcp --> pid
|
||||||
|
vw -.->|via Tinyauth<br/>when CT 109 lands| pid
|
||||||
|
classDef pending stroke-dasharray:4 4,color:#888
|
||||||
|
class vw pending
|
||||||
|
```
|
||||||
|
|
||||||
|
### MCP plane — gateway control, child workers
|
||||||
|
|
||||||
|
The MCP gateway on CT 104 is the OIDC-gated front; ~23 child MCP servers run on the same docker network (`ai-internal`). When CT 109 "observe" is built, the gateway moves to CT 109 and reaches CT 104's docker daemon via a socket-proxy; the children stay put.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
client[["Claude Code / Cursor / LobeChat"]]
|
||||||
|
gw["MCP gateway<br/>(CT 104 → CT 109 when 109 lands)<br/>mcp.nuclide.systems"]
|
||||||
|
client -- Bearer / OIDC --> gw
|
||||||
|
subgraph "CT 104 · ai-internal docker net"
|
||||||
|
direction TB
|
||||||
|
coderm[coder-mcp]
|
||||||
|
immm[mcp-immich]
|
||||||
|
n8nm[mcp-n8n]
|
||||||
|
fetch[mcp-fetch]
|
||||||
|
time[mcp-time]
|
||||||
|
cw[mcp-crawl4ai]
|
||||||
|
seq[mcp-sequential-thinking]
|
||||||
|
ham[home-assistant-mcp]
|
||||||
|
kr[kroki-mcp]
|
||||||
|
others[...18 more]
|
||||||
|
end
|
||||||
|
gw --> coderm
|
||||||
|
gw --> immm
|
||||||
|
gw --> n8nm
|
||||||
|
gw --> fetch
|
||||||
|
gw --> time
|
||||||
|
gw --> cw
|
||||||
|
gw --> seq
|
||||||
|
gw --> ham
|
||||||
|
gw --> kr
|
||||||
|
gw --> others
|
||||||
|
coderm -.spawns/controls.-> CoderWS[(Coder workspaces<br/>CT 111)]
|
||||||
|
ham -.bridges to.-> HAOS[(Home Assistant<br/>VM 100)]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data plane — what lives where
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TB
|
||||||
|
subgraph Tier1["Tier-1 / latency-sensitive · local NVMe"]
|
||||||
|
pid_d[Pocket-ID sqlite · CT 110]
|
||||||
|
immich_pg[Immich Postgres · CT 104]
|
||||||
|
shared_pg[shared-postgres · CT 104]
|
||||||
|
coder_pg[coder-db · CT 111]
|
||||||
|
gitea_pg[gitea-db · CT 111]
|
||||||
|
garage["Garage S3 · CT 104<br/>(moved off NFS 2026-05-19)"]
|
||||||
|
n8n_local["n8n data · CT 104<br/>(reverted from NFS 2026-05-19)"]
|
||||||
|
end
|
||||||
|
subgraph Bulk["Bulk · UNAS NFSv3"]
|
||||||
|
media["Immich media, Paperless docs,<br/>arr-stack media, audiobooks"]
|
||||||
|
coder_homes[Coder workspace homes · /mnt/pve/unas/services/coder]
|
||||||
|
gitea_data[Gitea repos · /mnt/pve/unas/services/gitea]
|
||||||
|
vw_data["Vaultwarden data<br/>(tier-1 leak — plan to move local)"]
|
||||||
|
end
|
||||||
|
subgraph BulkCIFS["Bulk · UNAS CIFS (Nextcloud only)"]
|
||||||
|
nc_data[Nextcloud user files]
|
||||||
|
end
|
||||||
|
subgraph Backup["Off-host backup"]
|
||||||
|
jottacloud[(jottacloud<br/>via Backrest)]
|
||||||
|
end
|
||||||
|
Tier1 -. WAL-G .-> garage
|
||||||
|
Bulk -. only media/data-dir .-> jottacloud
|
||||||
|
classDef gap fill:#5a2a2a,stroke:#c44,color:#fcc
|
||||||
|
class vw_data,jottacloud gap
|
||||||
|
```
|
||||||
|
|
||||||
|
The red blocks above are gaps: Vaultwarden is on NFS when it shouldn't be; off-host backup currently covers only one UNAS path, not service data. See `stacks/storage.md` for the verified state and the cleanup TODO list.
|
||||||
|
|||||||
Reference in New Issue
Block a user