diff --git a/containers/131-teddycloud.md b/containers/131-teddycloud.md new file mode 100644 index 0000000..3531cab --- /dev/null +++ b/containers/131-teddycloud.md @@ -0,0 +1,62 @@ +# 131 — `teddycloud` + +Self-hosted [TeddyCloud](https://github.com/toniebox-reverse-engineering/teddycloud), a +reimplementation of the Toniebox cloud backend — lets Tonie figurines play custom/ripped +audio content against a local server instead of the official cloud. + +Predates the client-enrollment convention entirely; nobody wrote it down. Found and +documented on 2026-07-06 after Oikos's drift detector (`oikos/drift.py`) flagged +`pve_id 131` as live on hubris (via `pct list`) with no `inventory.yaml` entry — see +[OIKOS.md](../OIKOS.md)'s Week 3 build-status note. `containers/132-rclone.md` had already +mentioned it in passing ("LXC 131 was already taken by an undocumented `teddycloud` +container"), and `hosts/strong.md`'s 2026-07-05 migration changelog fixed a DHCP conflict +for it — but it never got its own inventory entry or doc page until now. + +## At a glance + +- **Hostname:** `teddycloud` +- **Host:** hubris (confirmed via `pct config 131` run directly on hubris — the original + drift finding's `pct list` source) +- **IP:** `192.168.8.150` (static; was briefly `192.168.8.243` via DHCP until the + 2026-07-05 strong-migration work assigned it a fixed address — see hosts/strong.md) +- **Privilege:** unconfirmed (not checked — read-only investigation didn't need it) +- **Resources:** 1 core / 1 GiB RAM / 512 MiB swap / 16 GiB rootfs (`local-lvm`), Debian 12 + (bookworm) +- **Mounts:** `/mnt/library` (`mp0`) +- **Public hostname:** `teddy.hubris.network` → `192.168.8.150:8443` (see + [caddy (121)](121-caddy.md)) +- **Enrollment:** none — no `age_pubkey`, not a `homelab` CLI client. It's a plain + docker-compose app container, not a fleet-managed host. No action needed unless it starts + needing secrets. + +## Service + +Runs via `docker compose` at `/opt/teddycloud` — container `teddycloud-teddycloud-1`, +image `ghcr.io/toniebox-reverse-engineering/teddycloud:latest`, publishing `80`, `443`, +`8080`, and `8443`. Caddy routes `teddy.hubris.network` to the `:8443` port. + +## Risk notes + +**No Caddy forward-auth gate** — unlike `sab.hubris.network` on the same Caddyfile (which +is explicitly annotated `(Authentik forward-auth)`), `teddy.hubris.network` has no auth +annotation. It's reachable to anyone on the LAN/mesh who can resolve the hostname. Not +addressed as part of this doc pass — flagging it here since it's now visible in one place +for the first time. + +## Related + +- [Hubris host](../hosts/hubris.md) +- [Caddy (121)](121-caddy.md) — terminates `teddy.hubris.network` +- [rclone (132)](132-rclone.md) — landed on pve_id 132 specifically because 131 was already + taken by this container +- [Containers index](index.md) +- [OIKOS.md](../OIKOS.md) — drift detector that caught this + +## Changelog + +### 2026-07-06 — documented for the first time (drift-caught) + +Added to `inventory.yaml` and given this page. Verified live via read-only `pct config 131` ++ `pct exec 131 -- ...` on hubris: hostname, IP, resources, and that it runs via +`docker compose` (not a raw binary or systemd unit). No changes made to the running +container — this is pure documentation catch-up. diff --git a/containers/index.md b/containers/index.md index 9c6668a..ca8486d 100644 --- a/containers/index.md +++ b/containers/index.md @@ -19,6 +19,7 @@ Most containers live on [`hubris`](../hosts/hubris.md). Some have been | 128 | [trmnl](128-trmnl.md) | hubris | 192.168.8.211 | unpriv | 1 | 768 MiB | 8 GiB | — | `trmnl.hubris.network` | running | | 129 | [house](129-house.md) | **strong** | 192.168.8.244 | unpriv | 2 | 3 GiB | 8 GiB | — | `house.hubris.network` | running | | 130 | [grimmory](130-grimmory.md) | **strong** | 192.168.8.247 | priv | 1 | 2 GiB | 16 GiB | `/mnt/media_local` (via mp0) | `books.hubris.network` | running | +| 131 | [teddycloud](131-teddycloud.md) | hubris | 192.168.8.150 | — | 1 | 1 GiB | 16 GiB | `/mnt/library` | `teddy.hubris.network` (no auth gate) | running | || 132 | [rclone](132-rclone.md) | hubris | 192.168.8.214 | priv | 1 | 1 GiB | 8 GiB | `/mnt/library` (**ro**) | — (LAN-only UI `:5572`) | running | || 134 | [romm](134-romm.md) | **strong** | 192.168.8.249 | priv | 1 | 2 GiB | 16 GiB | `/mnt/media_local` (via mp0) | `roms.hubris.network` | running | diff --git a/hosts/house.yaml b/hosts/house.yaml index 17dc457..edcf89c 100644 --- a/hosts/house.yaml +++ b/hosts/house.yaml @@ -19,7 +19,8 @@ notes: - Docker host for Yuvomi (family planner). Created 2026-06-26. - Migrated from hubris to strong 2026-07-05 (Phase 1 of strong migration plan). - Runs Yuvomi container + WebDAV doc bridge to paperless -- 192.168.8.212 was the hubris IP before migration (now used by teddycloud via DHCP) +- 192.168.8.212 was the hubris IP before migration (briefly picked up by teddycloud via DHCP; teddycloud + has since been given a static IP, see hosts.teddycloud) age_pubkey: age1s07zs83ehtlg8jtwvr75ltc3c4cdlemfwjuxrwjtwkqxkl9tpggsyrzn2h see_also: - containers/129-house.md diff --git a/hosts/teddycloud.yaml b/hosts/teddycloud.yaml new file mode 100644 index 0000000..f39c622 --- /dev/null +++ b/hosts/teddycloud.yaml @@ -0,0 +1,44 @@ +# Generated by mcp/build_host_files.py from inventory.yaml. +# Do NOT edit by hand — your changes will be overwritten. +# Source of truth: ../inventory.yaml +name: teddycloud +kind: lxc +os: linux +role: teddycloud +state: active +host: hubris +pve_id: 131 +lan_ip: 192.168.8.150 +mesh_globals: + primary: netbird + accepted: + - netbird + - tailscale +mounts: +- /mnt/library +public_host: teddy.hubris.network +runs: +- teddycloud +services_hosted: +- name: teddycloud + url: https://teddy.hubris.network + backend: teddycloud + doc_page: containers/131-teddycloud.md + note: self-hosted TeddyCloud (Toniebox cloud reimplementation), docker compose + risk_notes: "no Caddy forward-auth gate (unlike sab.hubris.network on the same Caddyfile) \u2014 reachable\ + \ to anyone on the LAN/mesh who can resolve teddy.hubris.network; undocumented in inventory.yaml until\ + \ 2026-07-06 (drift-caught)" +notes: +- Docker host for TeddyCloud (ghcr.io/toniebox-reverse-engineering/teddycloud), a self-hosted reimplementation + of the Toniebox cloud backend. Debian 12 (bookworm). +- 1 core / 1 GiB RAM / 512 MiB swap / 16 GiB rootfs (local-lvm). +- "Predates the client-enrollment convention \u2014 undocumented in inventory.yaml until 2026-07-06, when\ + \ Oikos's drift detector (oikos/drift.py) caught pve_id 131 live on hubris (`pct list`) with no inventory\ + \ entry. Static IP assigned 2026-07-05 during the strong migration (was picking up 192.168.8.243 via\ + \ DHCP before that \u2014 see hosts/strong.md's 2026-07-05 changelog)." +- "No age_pubkey / homelab-context enrollment \u2014 not a homelab CLI client, just a docker-compose app\ + \ container. Not a required follow-up unless it needs secrets." +see_also: +- containers/131-teddycloud.md +mcp_endpoint: https://mcp.hubris.network/mcp +secrets_issuance_endpoint: https://secrets.hubris.network/issue diff --git a/infrastructure/topology.md b/infrastructure/topology.md index ae7a31a..ee1764d 100644 --- a/infrastructure/topology.md +++ b/infrastructure/topology.md @@ -3,7 +3,7 @@ # Topology (generated) -Source: [inventory.yaml](../inventory.yaml) — 2 hypervisors, 19 LXCs, 2 VMs, 2 workstations, 17 services. +Source: [inventory.yaml](../inventory.yaml) — 2 hypervisors, 20 LXCs, 2 VMs, 2 workstations, 18 services. Edge semantics: [oikos/ontology.yaml](../oikos/ontology.yaml). Operating model: [OIKOS.md](../OIKOS.md). ## Compute & ingress @@ -22,6 +22,7 @@ flowchart LR sophia["sophia
LXC 119
workshop
192.168.8.109"] mule_images["mule-images
LXC 120
photo-management
192.168.8.136"] caddy["caddy
LXC 121
reverse-proxy
192.168.8.175"] + teddycloud["teddycloud
LXC 131
teddycloud
192.168.8.150"] zimaos["zimaos
VM 100
nas-frontend-eval
192.168.8.195"] haos["haos
VM 108
home-automation
192.168.8.101"] end @@ -49,6 +50,7 @@ flowchart LR url_photos(["photos.hubris.network"]) -->|routes-to| mule_images url_proxmox_ui(["proxmox.hubris.network"]) -->|routes-to| hubris_sub url_secrets_issuance(["secrets.hubris.network"]) -->|routes-to| apps + url_teddycloud(["teddy.hubris.network"]) -->|routes-to| teddycloud url_trmnl(["trmnl.hubris.network"]) -->|routes-to| trmnl url_zimaos(["zimaos.hubris.network"]) -->|routes-to| zimaos ``` @@ -72,6 +74,7 @@ flowchart LR romm["romm"] -->|mounts| mnt_media_local seanime["seanime"] -->|mounts| mnt_media_local_anime sophia["sophia"] -->|mounts| mnt_library + teddycloud["teddycloud"] -->|mounts| mnt_library ``` ## Archaeology (destroyed nodes) diff --git a/inventory.yaml b/inventory.yaml index 3eed71c..47d2398 100644 --- a/inventory.yaml +++ b/inventory.yaml @@ -124,6 +124,14 @@ services: haos: backend: haos doc_page: vms/108-haos.md + teddycloud: + url: https://teddy.hubris.network + backend: teddycloud + doc_page: containers/131-teddycloud.md + note: self-hosted TeddyCloud (Toniebox cloud reimplementation), docker compose + risk_notes: no Caddy forward-auth gate (unlike sab.hubris.network on the same Caddyfile) — + reachable to anyone on the LAN/mesh who can resolve teddy.hubris.network; undocumented + in inventory.yaml until 2026-07-06 (drift-caught) homelab_mcp: backend: apps port: 9810 @@ -185,7 +193,8 @@ hosts: - Docker host for Yuvomi (family planner). Created 2026-06-26. - Migrated from hubris to strong 2026-07-05 (Phase 1 of strong migration plan). - Runs Yuvomi container + WebDAV doc bridge to paperless - - 192.168.8.212 was the hubris IP before migration (now used by teddycloud via DHCP) + - 192.168.8.212 was the hubris IP before migration (briefly picked up by teddycloud via + DHCP; teddycloud has since been given a static IP, see hosts.teddycloud) age_pubkey: age1s07zs83ehtlg8jtwvr75ltc3c4cdlemfwjuxrwjtwkqxkl9tpggsyrzn2h jellyfin: kind: lxc @@ -387,6 +396,28 @@ hosts: - Docker host for Grimmory (community fork of Booklore). Created 2026-06-29. - Migrated from hubris to strong 2026-07-05 (Phase 2d). Books on ludo-lvm. age_pubkey: age1uellsemnjrzgfg9fxw4jefpy05laxzggwnwhh6ny3wl7alyp6v8q0muxet + teddycloud: + kind: lxc + pve_id: 131 + host: hubris + os: linux + role: teddycloud + lan_ip: 192.168.8.150 + public_host: teddy.hubris.network + mounts: + - /mnt/library + state: active + notes: + - Docker host for TeddyCloud (ghcr.io/toniebox-reverse-engineering/teddycloud), a + self-hosted reimplementation of the Toniebox cloud backend. Debian 12 (bookworm). + - 1 core / 1 GiB RAM / 512 MiB swap / 16 GiB rootfs (local-lvm). + - Predates the client-enrollment convention — undocumented in inventory.yaml until + 2026-07-06, when Oikos's drift detector (oikos/drift.py) caught pve_id 131 live on + hubris (`pct list`) with no inventory entry. Static IP assigned 2026-07-05 during the + strong migration (was picking up 192.168.8.243 via DHCP before that — see + hosts/strong.md's 2026-07-05 changelog). + - No age_pubkey / homelab-context enrollment — not a homelab CLI client, just a + docker-compose app container. Not a required follow-up unless it needs secrets. seanime: kind: lxc pve_id: 133 diff --git a/ledger/2026-07.jsonl b/ledger/2026-07.jsonl new file mode 100644 index 0000000..717b034 --- /dev/null +++ b/ledger/2026-07.jsonl @@ -0,0 +1 @@ +{"ts": "2026-07-06T11:05:35+00:00", "agent": "mac-mini", "entity": "host:teddycloud", "action": "activate", "risk": "config_mutation", "verification": "homelab node teddycloud relations", "result": "ok"} diff --git a/oikos/cards/host-hubris.md b/oikos/cards/host-hubris.md index 98db010..9ae7e5d 100644 --- a/oikos/cards/host-hubris.md +++ b/oikos/cards/host-hubris.md @@ -9,9 +9,9 @@ - secrets: enrolled (age key present) ## Blast radius -- impacts: host:apps, host:auth-outpost, host:caddy, host:dns, host:gitea, host:haos, host:mule-images, host:nextcloud, host:nfs-export, host:paperless, host:sophia, host:trmnl, host:zimaos, service:proxmox_ui +- impacts: host:apps, host:auth-outpost, host:caddy, host:dns, host:gitea, host:haos, host:mule-images, host:nextcloud, host:nfs-export, host:paperless, host:sophia, host:teddycloud, host:trmnl, host:zimaos, service:proxmox_ui - affected by: mount:/mnt/library -- full blast radius: host:apps, host:auth-outpost, host:caddy, host:dns, host:gitea, host:haos, host:mule-images, host:nextcloud, host:nfs-export, host:paperless, host:sophia, host:trmnl, host:zimaos, service:artifacto, service:caddy, service:dns, service:gitea, service:haos, service:homelab_mcp, service:nextcloud, service:paperless, service:photos, service:proxmox_ui, service:secrets_issuance, service:trmnl, service:zimaos +- full blast radius: host:apps, host:auth-outpost, host:caddy, host:dns, host:gitea, host:haos, host:mule-images, host:nextcloud, host:nfs-export, host:paperless, host:sophia, host:teddycloud, host:trmnl, host:zimaos, service:artifacto, service:caddy, service:dns, service:gitea, service:haos, service:homelab_mcp, service:nextcloud, service:paperless, service:photos, service:proxmox_ui, service:secrets_issuance, service:teddycloud, service:trmnl, service:zimaos ## Safe actions - see the services this host runs for action-level risk classes diff --git a/oikos/cards/host-teddycloud.md b/oikos/cards/host-teddycloud.md new file mode 100644 index 0000000..f496a1e --- /dev/null +++ b/oikos/cards/host-teddycloud.md @@ -0,0 +1,20 @@ +# teddycloud (host:teddycloud) + +- kind: lxc (LXC 131) +- state: active +- runs-on: host:hubris +- role: teddycloud +- address: 192.168.8.150 +- mounts: /mnt/library +- doc: containers/131-teddycloud.md + +## Blast radius +- impacts: service:teddycloud +- affected by: host:hubris, mount:/mnt/library +- full blast radius: service:teddycloud + +## Safe actions +- see the services this host runs for action-level risk classes + +## Recent changes +- (none yet) diff --git a/oikos/cards/service-teddycloud.md b/oikos/cards/service-teddycloud.md new file mode 100644 index 0000000..23eb88d --- /dev/null +++ b/oikos/cards/service-teddycloud.md @@ -0,0 +1,19 @@ +# teddycloud (service:teddycloud) + +- backend: host:teddycloud +- url: https://teddy.hubris.network +- doc: containers/131-teddycloud.md +- risk notes: no Caddy forward-auth gate (unlike sab.hubris.network on the same Caddyfile) — reachable to anyone on the LAN/mesh who can resolve teddy.hubris.network; undocumented in inventory.yaml until 2026-07-06 (drift-caught) + +## Blast radius +- impacts: (none) +- affected by: host:teddycloud + +## Safe actions +- health-check — read_only (approval: none) +- view-logs — read_only (approval: none) +- view-docs — read_only (approval: none) +- restart — reversible_low (approval: none) + +## Recent changes +- (none yet)