diff --git a/containers/131-teddycloud.md b/containers/131-teddycloud.md new file mode 100644 index 0000000..09c7b3e --- /dev/null +++ b/containers/131-teddycloud.md @@ -0,0 +1,104 @@ +# 131 — `teddycloud` + +Open-source replacement server for Toniebox smart audio devices (Tonieboxes). Serves device content and API on port 443 and exposes a management web UI at `teddy.hubris.network`. + +## At a glance + +- **Hostname:** `teddycloud` +- **IP:** `192.168.8.214` (DHCP reservation) +- **Privilege:** privileged +- **Resources:** 1 core / 1 GiB RAM / 16 GiB rootfs (Debian 12) +- **Mounts:** `/mnt/library` (`mp0`) — TeddyCloud content at `/mnt/library/cloud/leon` +- **Public hostname:** none (LAN-only) + +## Role + +Replaces the Boxine cloud (`prod.de.bb-online.com`) as the backend for Leon's Toniebox. Tonieboxes connect on port 443 using a custom CA cert issued by TeddyCloud. Content (Tonies) is stored on the NAS at `/mnt/library/cloud/leon` and is accessible from the management UI. + +## Service / port map + +| Service | Listen | Notes | +|---------|--------|-------| +| TeddyCloud device API | `0.0.0.0:443` | HTTPS, TeddyCloud self-signed CA, Toniebox connects here | +| TeddyCloud HTTP | `0.0.0.0:80` | Redirects to 443 | +| TeddyCloud web UI | `0.0.0.0:8080` | HTTP management UI — fronted by Caddy at `teddy.hubris.network` | +| TeddyCloud web UI (HTTPS) | `0.0.0.0:8443` | HTTPS management UI (direct, not Caddy-fronted) | + +## Docker Compose + +`/opt/teddycloud/docker-compose.yml`: + +```yaml +services: + teddycloud: + image: ghcr.io/toniebox-reverse-engineering/teddycloud:latest + ports: + - "80:80" + - "443:443" + - "8080:8080" + - "8443:8443" + volumes: + - certs:/teddycloud/certs + - config:/teddycloud/config + - /mnt/library/cloud/leon:/teddycloud/content + - /mnt/library/cloud/leon:/teddycloud/library + restart: unless-stopped + +volumes: + certs: + config: +``` + +`certs` and `config` are Docker named volumes (runtime state). `content` and `library` are bind-mounted from `/mnt/library/cloud/leon` so audio content persists across container rebuilds and is browsable from the host. + +## Storage / config paths + +- `/opt/teddycloud/docker-compose.yml` — compose file +- Docker volume `teddycloud_certs` — TeddyCloud CA + server certs (generated on first boot) +- Docker volume `teddycloud_config` — TeddyCloud config +- `/mnt/library/cloud/leon/` — Tonie content + library (NAS bind mount) + +## Networking + +Two separate traffic paths — different IPs, no port 443 conflict: + +**Management UI (browser):** +``` +teddy.hubris.network → Technitium → 192.168.8.175 (Caddy) → 192.168.8.214:8080 +``` + +**Toniebox device traffic:** +``` +prod.de.bb-online.com → Technitium override → 192.168.8.214:443 (TeddyCloud direct) +``` + +Caddy terminates TLS for the management UI (IONOS DNS-01 wildcard cert). TeddyCloud terminates TLS for device traffic with its own self-signed CA — the Toniebox must have this CA installed. + +### DNS overrides in Technitium + +| Record | Type | Value | Purpose | +|--------|------|-------|---------| +| `teddy.hubris.network` | A | `192.168.8.175` | Management UI → Caddy (standard pattern) | +| `prod.de.bb-online.com` | A | `192.168.8.214` | Toniebox device traffic → TeddyCloud direct | + +The `prod.de.bb-online.com` override is Technitium-only — it intercepts Toniebox DNS locally without touching public DNS. The `dns-sync.py` cron on LXC 107 skips non-`hubris.network` records, so it stays local. + +## Toniebox onboarding + +To point a Toniebox at TeddyCloud: + +1. Download the TeddyCloud CA cert from the web UI: **Settings → TeddyCloud CA**. +2. Flash it to the Toniebox via SD card or firmware patch (procedure varies by hardware generation — see [upstream wiki](https://github.com/toniebox-reverse-engineering/teddycloud/wiki)). +3. The box resolves `prod.de.bb-online.com` to Technitium's override (`192.168.8.214`) and connects on port 443 using TeddyCloud's CA. + +## Related + +- [Caddy (121)](121-caddy.md) — LAN reverse proxy (`teddy.hubris.network → 192.168.8.214:8080`) +- [DNS (107)](../infrastructure/dns.md) — Technitium A records for `teddy.hubris.network` and `prod.de.bb-online.com` +- [Media permissions](../infrastructure/media-permissions.md) — NAS `/mnt/library` mount pattern + +## Changelog + +### 2026-06-29 — provisioned + +LXC 131 created (Debian 12, privileged, nesting=1). Docker installed. TeddyCloud running via Docker Compose at `/opt/teddycloud/`. Content bind-mounted from `/mnt/library/cloud/leon`. Caddy block added at `teddy.hubris.network → :8080`. Technitium A records: `teddy.hubris.network → 192.168.8.175` (Caddy), `prod.de.bb-online.com → 192.168.8.214` (device traffic direct). diff --git a/containers/index.md b/containers/index.md index b0681ca..399aba2 100644 --- a/containers/index.md +++ b/containers/index.md @@ -18,6 +18,7 @@ All containers live on [`hubris`](../hosts/hubris.md). Each row links to the per | 128 | [trmnl](128-trmnl.md) | 192.168.8.211 | unpriv | 1 | 768 MiB | 8 GiB | — | `trmnl.hubris.network` | running | | 129 | [house](129-house.md) | 192.168.8.212 | unpriv | 1 | 1344 MiB | 8 GiB | — | `house.hubris.network` | running | | 130 | [grimmory](130-grimmory.md) | 192.168.8.213 | priv | 1 | 2 GiB | 16 GiB | `/mnt/library` | `books.hubris.network` | running | +| 131 | [teddycloud](131-teddycloud.md) | 192.168.8.214 | priv | 1 | 1 GiB | 16 GiB | `/mnt/library` | `teddy.hubris.network` (LAN only) | running | ## Recently destroyed (kept for archaeology) diff --git a/infrastructure/dns.md b/infrastructure/dns.md index 011f7ee..71c15ae 100644 --- a/infrastructure/dns.md +++ b/infrastructure/dns.md @@ -33,9 +33,18 @@ address=/photos.hubris.network/192.168.8.175 address=/photos-new.hubris.network/192.168.8.175 address=/artifacto.hubris.network/192.168.8.175 address=/zimaos.hubris.network/192.168.8.175 +address=/teddy.hubris.network/192.168.8.175 address=/nfs-export.hubris.network/192.168.8.200 ``` +**Non-`hubris.network` override (Toniebox device traffic):** + +``` +address=/prod.de.bb-online.com/192.168.8.214 # → TeddyCloud (131) direct on :443 +``` + +This intercepts Toniebox DNS locally without touching public DNS. The `dns-sync.py` cron on LXC 107 skips non-`hubris.network` records — this entry is Technitium-only. + Note: `nfs-export.hubris.network` is the only `.hubris.network` entry that points to a non-HTTP service (NFSv4 on port 2049). It bypasses [caddy (121)](../containers/121-caddy.md) because NFS is L4, not HTTP — Caddy has nothing to do. ## Why split-horizon @@ -75,6 +84,9 @@ Either: ## Changelog +### 2026-06-29 — `teddy.hubris.network` added; `prod.de.bb-online.com` override added +TeddyCloud (LXC 131) provisioned. `teddy.hubris.network → 192.168.8.175` (Caddy → TeddyCloud web UI at :8080). Non-hubris override `prod.de.bb-online.com → 192.168.8.214` routes Toniebox device HTTPS traffic directly to TeddyCloud port 443 — this bypasses Caddy and is Technitium-only (dns-sync cron does not replicate non-hubris.network records to the NetBird managed zone). + ### 2026-06-28 — `plato.hubris.network` removed Plato (LXC 126) decommissioned. Technitium entry deleted; dns-sync cron reaped the NetBird managed zone record.