VMP is a Cloudflare-based video subscription platform with a Worker API, Nuxt web app, and shared TypeScript types.
- Monorepo packages
- Documentation map
- Deployment model (high level)
- Prerequisites
- Local setup
- Manual deploy commands
- Runtime secrets/vars
- API docs (
docs/) - Notes
| Package | Path | Role |
|---|---|---|
@vmp/api |
packages/api |
Cloudflare Worker API + D1/R2/KV integrations |
@vmp/web |
packages/web |
Nuxt 4 frontend deployed to Cloudflare Pages |
@vmp/shared |
packages/shared |
Shared TypeScript contracts |
@vmp/api-node |
packages/api-node |
Deno Deploy backup API (Postgres + S3 adapters) — see README |
@vmp/media-pipeline |
packages/media-pipeline |
Media VM: SVT Encore transcoding + Shaka HLS + R2 — see README |
@vmp/offloading |
packages/offloading |
R2↔Garage hot/cold tier orchestration — see README |
@vmp/moq-probe |
packages/moq-probe |
MoQ broadcast diagnostic probe — see README |
Core API and web packages do not ship separate READMEs; see AGENTS.md for architecture, auth, schema, and local dev.
| Document | Description |
|---|---|
| AGENTS.md | Canonical agent/dev guide: git workflow, D1 schema, auth, secrets, roadmap |
| DEPLOYMENT.md | Environment variables, CI/CD, multi-domain deploy |
| packages/api-node/README.md | Deno Deploy API backup, Postgres replication ingest |
| packages/media-pipeline/README.md | Encore transcoding orchestration, supervisor, webhooks, TTP logging |
| packages/media-pipeline/MIGRATION.md | Cutover guide from legacy podcast-host |
| packages/media-pipeline/systemd/README.md | vmp-supervisor systemd unit install and ops |
| packages/offloading/README.md | Garage compose, demote/promote scripts |
| packages/offloading/DEPLOYMENT.md | Docker/Compose deployment for offloading |
| packages/moq-probe/README.md | Live MoQ probe usage and recorder recommendations |
| .cursor/README.md | Cursor workspace git/deploy policy for agents |
| docs/pills-external-update-api.md | Pills external update API |
- Pushes to
mainrun staging deploy in.github/workflows/deploy.yml: API Worker + web Worker (vmp-web-worker-dev). - Version tags (
v*.*.*) run production deploy: API Worker + web Worker (vmp-web-worker-prod). - Frontend is Cloudflare Workers only (Nuxt SSR). Pages is deprecated.
- Deploy pipeline fails fast on type-checking before build/deploy:
@vmp/sharedtsc --noEmit@vmp/apitsc --noEmit@vmp/webnuxi prepare && nuxi typecheck
See DEPLOYMENT.md for env templates, secrets, and domain overrides.
- Node.js 20+ and npm 10+.
- Cloudflare account with:
- Two Workers per environment (API + Nuxt web frontend)
- D1 database
- R2 bucket
- KV namespaces
- Repository secrets configured for CI deploy:
CLOUDFLARE_API_TOKEN_STAGINGCLOUDFLARE_ACCOUNT_ID_STAGINGCLOUDFLARE_API_TOKEN_PRODCLOUDFLARE_ACCOUNT_ID_PROD
- Install dependencies:
npm ci
- Build service worker helper from TS source:
npm run build:sw-push --workspace=@vmp/web
- Type-check everything:
npm run typecheck
Full local dev (API on :8787, web on :3000, D1 migrations): AGENTS.md → Cursor Cloud-specific instructions.
These are useful for controlled/manual rollouts outside GitHub Actions.
- API deploy:
npm run deploy:api
- Web deploy (from
packages/webafternpm run build):- Staging Worker:
npm run deploy --workspace=@vmp/web - Production Worker:
npm run deploy:prod --workspace=@vmp/web
- Staging Worker:
Use Wrangler secrets for sensitive values (never commit secrets). Required values are documented in AGENTS.md and DEPLOYMENT.md (JWT, Stripe, Brevo, VAPID, RSS, TOTP encryption, etc.).
The existing local/watchfolder/rclone pipeline remains the default and is unchanged.
An optional cloud path can be enabled for direct source uploads + AWS Elemental MediaConvert.
Required API env vars (Worker):
MEDIA_CONVERT_ENABLED=1AWS_REGION(for S3 + MediaConvert, e.g.eu-central-1)AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN(optional, only when using temporary credentials)MEDIA_CONVERT_ENDPOINT(account-specific endpoint from MediaConvert console)MEDIA_CONVERT_ROLE_ARN(IAM role MediaConvert assumes)MEDIA_CONVERT_INPUT_BUCKET(S3 source uploads)MEDIA_CONVERT_OUTPUT_BUCKET(S3 transcode outputs)MEDIA_CONVERT_INPUT_PREFIX(optional, defaultmediaconvert-input)MEDIA_CONVERT_OUTPUT_PREFIX(optional, defaultmediaconvert-output)MEDIA_CONVERT_MAX_UPLOAD_MB(optional, default4096)MEDIA_CONVERT_PRICE_HD_PER_MIN(optional, default0.015; rough estimator)
AWS setup checklist:
- Create/choose two S3 prefixes/buckets for input and output.
- Create a MediaConvert IAM service role (
MEDIA_CONVERT_ROLE_ARN) with read access to input and write access to output. - Create an IAM principal for the Worker credentials with:
mediaconvert:CreateJob,mediaconvert:GetJobiam:PassRolescoped toMEDIA_CONVERT_ROLE_ARNs3:PutObjecton input prefixs3:GetObjecton output object prefixs3:ListBucketon output bucket (bucket-level action), scoped bys3:prefixcondition to the output prefix
- In MediaConvert console, copy the account endpoint into
MEDIA_CONVERT_ENDPOINT. - Run migration
packages/api/migrations/0017_media_convert_jobs.sql.
Notes:
- Current cloud profile is H.264/HLS with 720p only, fps capped at 30.
- Architecture is rendition-based and supports future expansion (480p/1080p/4K, alternate codecs).
- Usage/cost values are approximate normalized-minute estimates, not billing-grade accounting.
- API entrypoint is TypeScript (
packages/api/src/index.ts) referenced bypackages/api/wrangler.json. - Worker/service scripts that must remain JavaScript at runtime (for browser/service-worker execution) are generated from TypeScript sources during build.
- Media encoding on a VM is handled by
@vmp/media-pipeline(SVT Encore + orchestrator); optional Deno backup API by@vmp/api-node.