chore: rename project from podpuddle to podsteadr
Renames the repo directory and every podpuddle/PODPUDDLE reference across code, config, and docs to podsteadr/PODSTEADR (package names, Docker Compose project/service/volume names, env var names, UI/RSS strings). Existing Docker volume data (uploaded blobs, mediamtx recordings, the server's sqlite DB and its nostr identity key) was migrated to new podsteadr_-prefixed volumes with matching filenames so it isn't orphaned by the rename.
This commit is contained in:
+13
-13
@@ -1,4 +1,4 @@
|
||||
# podpuddle — project status & handoff
|
||||
# podsteadr — project status & handoff
|
||||
|
||||
_Last updated: 2026-07-10. State: **working, verified end-to-end, parked.**_
|
||||
|
||||
@@ -18,7 +18,7 @@ fully standalone compose stack today.
|
||||
## How to resume
|
||||
|
||||
```sh
|
||||
cd ~/podpuddle
|
||||
cd ~/podsteadr
|
||||
docker compose up -d # data volumes were kept; everything resumes as-is
|
||||
node scripts/e2e.mjs # 14 automated checks against the running stack
|
||||
```
|
||||
@@ -26,14 +26,14 @@ node scripts/e2e.mjs # 14 automated checks against the running stack
|
||||
Open http://localhost:8095 and log in with a NIP-07 extension (Alby, nos2x).
|
||||
For a non-localhost box, edit `.env` (`PUBLIC_HOST=…`) and `docker compose up -d --build`.
|
||||
|
||||
State that persists in the named volumes: `podpuddle-data` (SQLite DB, the
|
||||
State that persists in the named volumes: `podsteadr-data` (SQLite DB, the
|
||||
server's nostr key in `config/server-nostr-key`, admin = first pubkey that ever
|
||||
logged in), `blossom-data` (media blobs), `mediamtx-recordings` (stream
|
||||
recordings, 7-day retention). `docker compose down -v` wipes all of it.
|
||||
|
||||
Note: the automated e2e run left test data behind (an "E2E Test Show" podcast
|
||||
with 2 episodes, test streams, and the e2e identity as **admin**). The e2e
|
||||
identity's secret key is in `/tmp/podpuddle-e2e-key` (hex). For real use you
|
||||
identity's secret key is in `/tmp/podsteadr-e2e-key` (hex). For real use you
|
||||
probably want a clean slate: `docker compose down -v && docker compose up -d`,
|
||||
then log in with your own extension first so *your* pubkey becomes admin.
|
||||
|
||||
@@ -43,9 +43,9 @@ Three containers on one compose network:
|
||||
|
||||
| Container | Image | Host ports | Role |
|
||||
|---|---|---|---|
|
||||
| `podpuddle` | built from `Dockerfile` (node:22 + ffmpeg) | 8095 | Fastify API + built Vue UI + RSS feeds |
|
||||
| `podpuddle-mediamtx` | `bluenviron/mediamtx:1.19.2` | 1935 (RTMP), 8889 (WHIP), 8189/udp (ICE), 8890→8888 (HLS) | ingest + HLS output + recording |
|
||||
| `podpuddle-blossom` | `ghcr.io/hzrd149/blossom-server:4` (4.4.1) | 8098→3000 | sha256-addressed media blobs |
|
||||
| `podsteadr` | built from `Dockerfile` (node:22 + ffmpeg) | 8095 | Fastify API + built Vue UI + RSS feeds |
|
||||
| `podsteadr-mediamtx` | `bluenviron/mediamtx:1.19.2` | 1935 (RTMP), 8889 (WHIP), 8189/udp (ICE), 8890→8888 (HLS) | ingest + HLS output + recording |
|
||||
| `podsteadr-blossom` | `ghcr.io/hzrd149/blossom-server:4` (4.4.1) | 8098→3000 | sha256-addressed media blobs |
|
||||
|
||||
Key flows:
|
||||
|
||||
@@ -55,7 +55,7 @@ Key flows:
|
||||
directly on any API route (scripting). First pubkey to log in becomes admin.
|
||||
- **Episode upload** — browser hashes the file (`crypto.subtle`, ≤2 GB), signs a
|
||||
kind-24242 BUD-02 auth via NIP-07, PUTs **directly to blossom** (file never
|
||||
transits podpuddle), then registers `{sha256, size, …}` with
|
||||
transits podsteadr), then registers `{sha256, size, …}` with
|
||||
`POST /api/podcasts/:id/episodes`; server HEAD-verifies the blob before
|
||||
accepting. Enclosure URL = `<blossom>/<sha256>.mp4`.
|
||||
- **RSS** — `GET /feeds/:podcastId/feed.xml`, RSS 2.0 + itunes + podcast
|
||||
@@ -68,7 +68,7 @@ Key flows:
|
||||
travels as `?key=` (OBS stream key) or WHIP `Bearer`, is stored only as a
|
||||
sha256 hash, and never appears in viewer URLs. MediaMTX delegates auth to
|
||||
`POST /api/mediamtx/auth` (2xx = allow); reads are public.
|
||||
- **Status / NIP-53** — podpuddle polls the MediaMTX API (`:9997/v3/paths/list`,
|
||||
- **Status / NIP-53** — podsteadr polls the MediaMTX API (`:9997/v3/paths/list`,
|
||||
every 3 s) and flips `planned → live → ended` (the stock MediaMTX image has no
|
||||
shell, so `runOn*` curl hooks are impossible — polling is deliberate). On each
|
||||
transition it (re)publishes the kind-30311 live event **signed by the server's
|
||||
@@ -76,7 +76,7 @@ Key flows:
|
||||
with the user `p`-tagged as `host`, to the relay list in Settings. 30311 is
|
||||
replaceable, which is why the server key signs rather than the user's.
|
||||
- **Recordings** — MediaMTX records fmp4 segments to the shared volume;
|
||||
podpuddle mounts it read-only, lists per-stream files, and
|
||||
podsteadr mounts it read-only, lists per-stream files, and
|
||||
`POST /api/streams/:id/recordings/publish` remuxes (`ffmpeg -c copy
|
||||
+faststart`), uploads to blossom **with the server's key** (the only
|
||||
server-signed upload path), and creates the episode.
|
||||
@@ -112,7 +112,7 @@ frontend/ # Vue 3 + Vite + Tailwind + Pinia
|
||||
admin claim, episode blob verification, feed ETag/304, stream key
|
||||
create/verify/rotate, webhook allow/deny paths, settings admin gating).
|
||||
- `node scripts/e2e.mjs` against the compose stack — **14/14**.
|
||||
- Live leg (manual, via ffmpeg in the podpuddle container):
|
||||
- Live leg (manual, via ffmpeg in the podsteadr container):
|
||||
- RTMP publish with the right key → HLS `index.m3u8` 200 (after MediaMTX's
|
||||
`?cookieCheck=1` redirect — use `curl -L`).
|
||||
- Wrong key → connection reset by MediaMTX (webhook denial confirmed live).
|
||||
@@ -139,7 +139,7 @@ frontend/ # Vue 3 + Vite + Tailwind + Pinia
|
||||
streaming/seeking is degraded. Options later: upgrade to the Deno rewrite,
|
||||
or front blossom with nginx.
|
||||
3. **Split-horizon blossom URL**: browsers use `http://<host>:8098`, but inside
|
||||
the podpuddle container that address doesn't exist. `BLOSSOM_URL_INTERNAL`
|
||||
the podsteadr container that address doesn't exist. `BLOSSOM_URL_INTERNAL`
|
||||
(compose sets `http://blossom:3000`) is used server-side whenever the active
|
||||
blossom URL equals the bundled default; feeds always carry the public URL.
|
||||
4. **Stock MediaMTX image has no shell** — `runOnReady`-style hooks can't run
|
||||
@@ -154,7 +154,7 @@ frontend/ # Vue 3 + Vite + Tailwind + Pinia
|
||||
## Remaining work
|
||||
|
||||
- **Archipelago packaging** (the original deployment target, archy repo):
|
||||
`apps/podpuddle/manifest.yml` + `apps/podpuddle-mediamtx` + `apps/podpuddle-blossom`
|
||||
`apps/podsteadr/manifest.yml` + `apps/podsteadr-mediamtx` + `apps/podsteadr-blossom`
|
||||
following the `apps/btcpay-server` (dependencies) + `apps/monero-ui`
|
||||
(`container.build` on `/opt/archipelago/docker/...`) patterns; bind volumes
|
||||
under `/var/lib/archipelago/<app>`; add ports **8095, 1935, 8889, 8189/udp,
|
||||
|
||||
Reference in New Issue
Block a user