// home_infrastructure · the template problem

Not a Sonos remote. A home-server framework that happens to play music first.

FastAPI · SoCo · Docker · uv · the first service of N
// see it work

A live code demonstration synced to music with generated narration — the app controlling real Sonos speakers, end to end. (Produced by ClearSpring Studio — the same pipeline that produces client video work.)

Not a Sonos remote. A home-server framework that happens to play music first.
N×1
one template, copied by every future home service

The real decision here is structural, not functional. A web controller for Sonos is a weekend project. The work was deciding to build it as a reusable template — Docker, env-sealed secrets via Infisical, a static SPA on top of a clean JSON API, health checks, structured logging, diagnostics mail — so the second service (media server, etc.) is a copy-and-modify exercise, not a greenfield build.

The "framework" is the convention this repo demonstrates. Future services are their own repos that copy this shape; the server just runs N independent Compose projects. YAGNI applied to infrastructure: build one, make it copyable, defer the multi-service tree until a second service actually exists.

// every home service copies this shape
# every home service copies this shape
$ docker compose up -d sonoskd     # → http://localhost:8557
GET  /zones                   # live state + what's playing
POST /zones/{id}/scene        # recall {rooms grouped + favorite + volume}
GET  /api/art?uid={uid}        # album art proxied (SSRF-safe)

// structural decisions worth knowing

  • D7 · discovery
    Seed-IP first, multicast as fallback. SSDP multicast is flaky on multi-NIC hosts — docker and tailscale bridges ate the probe. Connect to one known speaker, read the household off it. Reliable where the "correct" discovery isn't.
  • D7b · the mesh
    The controller runs on an identity-based mesh (Tailscale) by default, so the app itself ships no auth — tailnet membership is the boundary, not a login screen. Trust moves to the network layer; the app stays stateless about identity. The same mesh serves every service I operate (Universal Agent's surface, the render box, this controller) under one private network that never touches the public internet.
  • D8 · favorites
    A Sonos Favorite is a pointer, not a stream. SetAVTransportURI rejects it (UPnP 402). The accepted meta lives in the favorite's <r:resMD>, complete with the service-auth token. Replay that, not the outer favorite.
  • D10 · art proxy
    Album art is proxied through the box because a phone reaching the controller over Tailscale can't hit the speaker's LAN address. The proxy only fetches from UIDs in our zone map, path-validated — so it can't be turned into an SSRF.
  • D11 · scenes
    Scene recall isolates to the scene's rooms: unjoin → regroup the subset → play → set group volume. It never disturbs rooms outside the scene. The hard part of a "preset" isn't saving state, it's not clobbering adjacent state.
  • OK... go ahead and ask...
    Does this really have the complete functionality of YouTube Music with universal search, including by current vibe?