Skip to content

F.8: PeerTube bundle — federated video platform#17

Open
kh0pper wants to merge 1 commit intof7-mastodon-bundlefrom
f8-peertube-bundle
Open

F.8: PeerTube bundle — federated video platform#17
kh0pper wants to merge 1 commit intof7-mastodon-bundlefrom
f8-peertube-bundle

Conversation

@kh0pper
Copy link
Copy Markdown
Owner

@kh0pper kh0pper commented Apr 12, 2026

Summary

Stacked on F.7 (Mastodon). Heaviest bundle in the federated line — hardware gate refuses install on <16 GB total RAM and <500 GB disk. Fourth consumer of F.0's storage-translators (PeerTube's PEERTUBE_OBJECT_STORAGE_* envelope — eight bucket-name variables plus ACL + region).

  • chocobozzz/peertube:production-bookworm + postgres:15 + redis:7 = 3 containers. peertube on crow-federation; DB + redis isolated. Transcoding uses embedded ffmpeg; concurrent-upload RAM spikes 3-5 GB per worker, so PEERTUBE_TRANSCODING_CONCURRENCY defaults to 1 and should stay low on 16 GB hosts.
  • 14 MCP tools: pt_status, pt_list_channels, pt_list_videos (local/federated/subscriptions), pt_upload_video (multipart ≤2 GB; 10-min timeout — web UI handles resumable for larger), pt_search, pt_subscribe/pt_unsubscribe, pt_rate_video, inline pt_block_user, queued admin pt_block_server/pt_defederate, pt_review_reports, pt_report_remote (with predefined_reasons taxonomy: violentOrAbusive / hatefulOrAbusive / privacy / rights / ...), pt_media_prune (surfaces the node dist/scripts/prune-storage.js recipe).
  • Storage: S3 is load-bearing, not optional. A single 1080p30 video is ~500 MB in transcoded variants; an active channel fills 500 GB within months. Set PEERTUBE_S3_* and scripts/configure-storage.mjs populates the eight-bucket envelope via storage-translators.peertube().
  • Consent text (EN/ES) hard-stops: REFUSED on <16 GB RAM + <500 GB disk, transcoding RAM 3-5 GB per concurrent upload, DMCA + defederation-for-copyright risks called out explicitly.

Test plan

  • node --check on all JS files
  • bash -n on shell scripts
  • MCP server boots via createPeertubeServer() with no env set
  • docker compose config parses with required env set
  • JSON parse on manifest, package, registry
  • npm run check passes
  • End-to-end install on a 32 GB / 2 TB test host (deferred — this bundle is hostile to small test rigs by design)
  • Video upload → transcoding → HLS playback round-trip
  • S3 migration exercise (migrate-videos-to-object-storage.js)
  • Queued admin block_server + defederate (needs F.11 panel UI)

Integration notes

  • Fourth storage-translator consumer. With F.4/F.5/F.7/F.8 all using the translator surface, we've now exercised four different env-var conventions:
    • Funkwhale: AWS_STORAGE_BUCKET_NAME + AWS_S3_ENDPOINT_URL
    • Pixelfed: AWS_BUCKET + FILESYSTEM_CLOUD=s3 + PF_ENABLE_CLOUD
    • Mastodon: S3_BUCKET + S3_PROTOCOL + S3_HOSTNAME + AWS_ACCESS_KEY_ID
    • PeerTube: PEERTUBE_OBJECT_STORAGE_* (eight bucket-name variants + ACL)
  • resolveChannelId() helper for name@host → id via /api/v1/video-channels/{handle}. Not Mastodon-compatible, so no hoist to mastodon-api.js.
  • chocobozzz/peertube:production-bookworm floating tag — will pin to specific release (e.g., v7.x.y) before merge.

Rollout position

  • F.0 → F.7 shipped
  • F.8 (this PR) — last small-AP bundle
  • Next: F.11 identity attestation (independent) + F.12 cross-app bridging (F.3 Matrix + F.7 Mastodon both now present)

🤖 Generated with Claude Code

Stacked on F.7 (Mastodon). Heaviest bundle in the federated line.
Fourth consumer of F.0's storage-translators (PEERTUBE_OBJECT_STORAGE_*
envelope) — validates the translator surface across four different env
var conventions.

PeerTube is the fediverse's YouTube-alternative: videos served via HLS
(HTTP) + WebTorrent (P2P seeding between viewers), federated channels,
remote subscriptions. Three-container bundle: peertube (app +
transcoding + HLS generator) + postgres + redis.

Bundle (bundles/peertube/):

- manifest.json  consent_required with EN/ES covering federation reach,
                 storage-unbounded-without-S3 constraint (a single
                 1080p30 video is ~500 MB in transcoded variants),
                 transcoding RAM spikes (3-5 GB per concurrent upload),
                 hardware gate (REFUSED on <16 GB total RAM and <500 GB
                 disk; warn below 32 GB / 2 TB), DMCA liability, and
                 defederation risk for copyright violations.
                 min_ram_mb=4000, recommended=8000; min_disk=100 GB,
                 recommended=2 TB.
- docker-compose.yml  chocobozzz/peertube:production-bookworm +
                 postgres:15-alpine + redis:7-alpine. peertube on
                 crow-federation; DB + redis isolated. mem_limits:
                 peertube=6g (transcoding headroom), postgres=512m,
                 redis=256m. Full PEERTUBE_OBJECT_STORAGE_* passthrough
                 (eight bucket-name env vars covering videos /
                 streaming_playlists / web_videos / originals /
                 user_exports + ACL + region). Transcoding concurrency
                 tunable via PEERTUBE_TRANSCODING_CONCURRENCY;
                 per-user quota PEERTUBE_VIDEO_QUOTA_MB.
- server/server.js  14 MCP tools: pt_status, pt_list_channels,
                 pt_list_videos (local/federated/subscriptions),
                 pt_upload_video (multipart; up to ~2 GB single-request,
                 10-min timeout — web UI handles larger via resumable
                 tus-style chunks), pt_search (videos + channels),
                 pt_subscribe / pt_unsubscribe (by name@host handle),
                 pt_rate_video (like/dislike/none),
                 pt_block_user (inline, rate-limited),
                 pt_block_server / pt_defederate (admin, QUEUED),
                 pt_review_reports (open abuses), pt_report_remote
                 (with predefined_reasons taxonomy:
                 violentOrAbusive / hatefulOrAbusive /
                 spamOrMisleading / privacy / rights / ...),
                 pt_media_prune (surfaces the node
                 dist/scripts/prune-storage.js recipe — PeerTube
                 schedules this automatically).
                 resolveChannelId() helper for handle→id via
                 /api/v1/video-channels/{handle}. Bearer auth via
                 PEERTUBE_ACCESS_TOKEN (obtained via OAuth2 password
                 grant against /api/v1/oauth-clients/local +
                 /api/v1/users/token).
- server/index.js  stdio transport.
- panel/peertube.js + panel/routes.js  Nest panel: instance status +
                 recent local videos with duration/views/likes.
                 XSS-safe. /api/peertube/{status,videos}.
- skills/peertube.md  setup recipe (PEERTUBE_SECRET generation,
                 first-boot admin capture from logs, npm run
                 reset-password, OAuth token dance), S3-is-load-bearing
                 guidance (migrate-videos-to-object-storage.js),
                 upload/search/subscribe examples, moderation ladder
                 (predefined_reasons catalog), DMCA responsibility
                 note, troubleshooting (transcoding OOM, disk pressure,
                 federation retries).
- scripts/post-install.sh  180s health wait, configure-storage.mjs
                 invocation when S3 vars set, initial root password
                 capture from `docker logs ... | grep Username` with
                 immediate rotation recipe, Caddy + token steps.
- scripts/configure-storage.mjs  imports storage-translators.peertube()
                 and writes the eight-bucket envelope to .env. Inline
                 fallback in installed-mode.
- scripts/backup.sh  pg_dump + config tar by default; --with-videos
                 flag includes on-disk video store (optional — usually
                 hundreds of GB). S3-backed video explicitly NOT in
                 scope. Prints loud warning: PEERTUBE_SECRET rotation
                 breaks every federated follow.
- package.json  MCP + zod deps.

Integrations with shipped F-series:

- F.0 storage-translators.peertube()  fourth consumer (after F.4/F.5/F.7).
  Validates translator surface across AWS_STORAGE_BUCKET_NAME (Funkwhale),
  AWS_BUCKET + FILESYSTEM_CLOUD (Pixelfed), S3_BUCKET + S3_PROTOCOL
  (Mastodon), PEERTUBE_OBJECT_STORAGE_*_BUCKET_NAME (eight variants for
  PeerTube). If any translator needs adjustment, we fix it here before
  F.11/F.12.
- F.0 rate limiter  content + moderation verbs. Read-only uncapped.
- F.0 hardware gate  PeerTube is the bundle that most exercises the
  gate's "refuse on insufficient hardware" path — min 16 GB total host
  RAM, min 500 GB disk.

Human-in-the-loop moderation:

- Inline (rate-limited): pt_block_user, pt_rate_video with rating=none,
  pt_report_remote (with predefined_reasons).
- Queued (operator confirms in Nest within 72h): pt_block_server,
  pt_defederate.
- Media prune surfaced as `node dist/scripts/prune-storage.js` recipe
  rather than inline execution (PeerTube's own pattern — scheduler
  handles the normal case at PEERTUBE_VIDEOS_CLEANUP_REMOTE_INTERVAL).

Image tag policy:

- chocobozzz/peertube:production-bookworm floating tag — will pin to a
  specific release (e.g., v7.x.y) before merge per the image-tag policy.
  PeerTube's release cadence is quarterly with security backports;
  floating tag is safe for the dev branch.

Verified:

- node --check on all JS files
- bash -n on shell scripts
- MCP server boots via createPeertubeServer() with no env set
- docker compose config parses with required env set
- JSON parse on manifest
- (registry, superpowers, CLAUDE.md ref added in amend)

Remaining:

- F.11 identity attestation (independent; ties per-app keys to Crow root)
- F.12 cross-app bridging (F.3 Matrix + F.7 Mastodon both shipped — unblocked)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant