Skip to content

docs(lambda): add migration guide + non-Lambda Dockerfile example#915

Open
jrusso1020 wants to merge 1 commit into
docs-lambda-deployfrom
docs-lambda-migration
Open

docs(lambda): add migration guide + non-Lambda Dockerfile example#915
jrusso1020 wants to merge 1 commit into
docs-lambda-deployfrom
docs-lambda-migration

Conversation

@jrusso1020
Copy link
Copy Markdown
Collaborator

@jrusso1020 jrusso1020 commented May 17, 2026

What

Two adopter-facing artifacts that close out Phase 6b's user-facing surface:

  1. docs/deploy/migrating-to-hyperframes-lambda.mdx — side-by-side concept mapping for users coming from another one-command-deploy video renderer. Verb mapping (deploy / render / progress / destroy / sites / policies), composition format (plain HTML vs JSX), render config, and a list of intentional differences (no HDR in distributed mode, no webm, gpu-mode=software requirement, fail-closed font fetch, local stack-state files, narrow-after-first-deploy IAM pattern). Closes with a migration checklist.
  2. examples/k8s-jobs/Dockerfile.example + README.md — reference Dockerfile for adopters who want to run HyperFrames distributed renders outside Lambda. Bakes Node 22 + chrome-headless-shell + ffmpeg + the producer source. Built by adopters; not published to a registry.

Why

Per DISTRIBUTED-RENDERING-PLAN.md § 11 Phase 6b PR 6.8: the Lambda surface is the recommended path, but the OSS contract has always been "the distributed primitives are runtime-agnostic — Lambda is one adapter." Without this PR, adopters running Kubernetes Jobs / Argo Workflows / Cloud Run Jobs / ECS Fargate have to derive the runtime image from scratch by reading the Lambda Dockerfile. This PR collapses that to "build the example Dockerfile."

How

  • Migration guide registered under the existing "Deploy" group in docs/docs.json (added by the previous PR in this stack).
  • Per repo convention, no competitor framework is named in any public artifact. The migration guide is framed for "users migrating from another one-command-deploy renderer" and lets adopters self-identify.
  • .gitignore extended to negate examples/k8s-jobs/ the same way examples/aws-lambda/ is negated — the repo blanket-ignores examples/* and opts tracked subdirs back in.
  • The Dockerfile README points adopters at packages/aws-lambda/src/handler.ts as the reference adapter for how to wire the per-activity event shape into their own orchestrator.

Test plan

  • Mintlify nav (docs/docs.json) parses — verified the new entry alongside the deploy guide added in docs(lambda): add docs/deploy/aws-lambda.mdx deployment guide #914
  • .gitignore rule round-trips: git check-ignore -v examples/k8s-jobs/... now reports the negation
  • Maintainer-run docker build of examples/k8s-jobs/Dockerfile.example — out of scope for an OSS PR since the image isn't published; the build instructions are documented inline and match the chrome-headless-shell version pinned at 131.0.6778.139 that the producer already uses

Stacks on #909, #910, #912, #913, and #914.

🤖 Generated with Claude Code

Copy link
Copy Markdown
Collaborator Author

Copy link
Copy Markdown
Collaborator

@miguel-heygen miguel-heygen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI green (same pattern as #914 — all real checks pass, Graphite mergeability pending is expected for a stacked PR).

Migration guide (migrating-to-hyperframes-lambda.mdx) — the concept-mapping table is thorough and accurate. The "What HyperFrames does differently" section is the most useful part: GPU determinism, failClosedFontFetch, no HDR, no webm distributed, and local state files are all real footguns that a migrating adopter would hit without warning. Good to have them front-loaded.

hyperframes lambda sites create ./project appears in the concept table (mapping to "one-shot site upload") but doesn't appear anywhere in PR #914's CLI guide — if that subcommand isn't implemented yet, this row will confuse adopters. Either add it to #914 or mark it as coming soon.

FPS note — "24, 30, 60 only — non-integer NTSC rationals are an in-process-only feature" is accurate and good to call out explicitly.

Migration checklist — solid 6-step sequence. Step 2 links to /concepts (correct path) and the /hyperframes skill. Step 5's policies user > infra/iam/hyperframes.json shell redirect is a nice concrete pattern.

Dockerfile (examples/k8s-jobs/Dockerfile.example) — well-commented and production-grade:

  • chrome-headless-shell@131.0.6778.139 pinned explicitly — correct approach, adopters should pin this to their validated version.
  • tini as PID 1 is the right call for SIGTERM propagation in Cloud Run / Fargate.
  • Running bun install --frozen-lockfile then uninstalling bun keeps the runtime image clean.
  • The default CMD prints {producerVersion, chromePath} JSON — useful health-check / smoke test.

One minor issue: libcairo2, libcups2, libdbus-1-3, libglib2.0-0, libnspr4, libpango-1.0-0 are listed in the apt install block but not in the inline comment explaining "minimum set chrome-headless-shell needs". The comment says it lists the minimum set; listing them there but not in the comment is harmless but slightly confusing. Consider either expanding the comment or removing the "(the minimum set ...)" qualifier.

The .gitignore negation for examples/k8s-jobs/** is correct — matches the existing !examples/aws-lambda/** pattern.

Approved.

Copy link
Copy Markdown
Collaborator

@vanceingalls vanceingalls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additive review — @miguel-heygen already covered the concept-mapping table accuracy, the "What HyperFrames does differently" section, the sites create vs #914 cross-reference, the FPS note, the migration checklist, tini, the bun install --frozen-lockfile pattern, and the libcairo2-block-vs-comment mismatch. The findings below are gaps not raised in that review.

Strengths (additive to Miguel's):

  • Migration guide footguns (migrating-to-hyperframes-lambda.mdx:46-66) trace cleanly to actual code paths — BROWSER_GPU_NOT_SOFTWARE (packages/engine/src/utils/assertSwiftShader.ts), FONT_FETCH_FAILED (packages/producer/src/services/deterministicFonts.ts), FORMAT_NOT_SUPPORTED_IN_DISTRIBUTED (packages/producer/src/services/distributed/plan.ts). Adopters who hit any of these can grep the codebase from the doc.
  • chunk-size=240 / max-parallel-chunks=16 defaults in the render-config table (migrating-to-hyperframes-lambda.mdx:36-37) match packages/cli/src/commands/lambda.ts:100-101 exactly.

Important — Chrome version pin diverges from the rest of the stack (examples/k8s-jobs/Dockerfile.example:73)
CHROME_HEADLESS_SHELL_VERSION=131.0.6778.139 is the version this Dockerfile installs. Searching the repo:

  • packages/cli/src/browser/manager.ts:7 pins CHROME_VERSION = \"131.0.6778.85\" (the dev path).
  • Dockerfile.test:56, packages/cli/src/docker/Dockerfile.render:19, packages/aws-lambda/scripts/build-zip.ts:400 all use chrome-headless-shell@stable (floating, currently resolves to a different patch).

The migration guide itself emphasizes byte-level determinism: "the per-chunk concat-copy assumes byte-level reproducibility" (migrating-to-hyperframes-lambda.mdx:48). Adopters who run Lambda plan + non-Lambda renderChunk in the same pipeline with these two image families will be on different Chrome patches across chunk boundaries, which is exactly the failure mode the guide warns about. Pin all three to the same version (preferably the producer's actual .85, or upgrade the producer first and pin everything to .139).

Important — PR-body claim is not verifiable
The PR body says: "matches the chrome-headless-shell version pinned at 131.0.6778.139 that the producer already uses." Grepping the repo finds no .139 pin anywhere outside this PR. Either the claim is stale or there's a producer-side pin I missed — if it's the latter, citing the file would help; if it's the former, update the body so reviewers don't take the parity claim at face value.

Important — Container runs as root (examples/k8s-jobs/Dockerfile.example)
No USER directive. tini is wired up correctly for PID 1 but Chrome (+ everything else) runs as root. Adopters will copy-paste this Dockerfile into K8s / Cloud Run / Fargate — those platforms' best-practice (and some org-level admission policies) require non-root. The aws-lambda adapter sidesteps this because Lambda's execution model isn't a long-running container, but the K8s example is. Suggest:

RUN groupadd --system --gid 1001 hyperframes && \
    useradd  --system --uid 1001 --gid hyperframes --shell /usr/sbin/nologin hyperframes
# ...after the COPY blocks...
RUN chown -R hyperframes:hyperframes /app /opt/chrome
USER hyperframes

Adopters who need root for some platform reason can override; non-root should be the default.

Nit — Probably-dead apt deps (examples/k8s-jobs/Dockerfile.example:46,55)
wget and xz-utils are in the apt block but I don't see either invoked downstream — @puppeteer/browsers does its HTTPS + extraction in Node. If they're vestigial from a previous draft, dropping them shaves a few MB and shrinks the supply-chain surface. (If they're needed and I missed where, ignore.)

Note — sites HeadObject status (migrating-to-hyperframes-lambda.mdx:14)
The doc says "HeadObject 200" (correct per S3 API). The implementation comment at packages/cli/src/commands/lambda/sites.ts:8 says "HeadObject-204" — code comment is loose, doc is right. Not a doc finding; just flagging in case James wants to fix the code comment in a sibling PR.

Stack-aware: this is an OSS doc + example-Dockerfile PR with all required CI green, prior approval from Miguel, and no correctness risk to the runtime path. The Chrome-version finding is the highest-leverage of the three importants because adopters who hit it will silently get non-deterministic renders rather than a loud failure — worth landing as a follow-up commit on this PR, but not a hard block.

Verdict: APPROVE
Reasoning: Documentation + reference example, no runtime code paths changed, prior reviewer covered the core content; my findings are quality nudges on an adopter-facing artifact, not correctness blockers.

Review by Vai

@jrusso1020 jrusso1020 force-pushed the docs-lambda-deploy branch from 9c7e205 to 8d6ffe5 Compare May 17, 2026 00:31
@jrusso1020 jrusso1020 force-pushed the docs-lambda-migration branch from eff27f7 to 5be0bad Compare May 17, 2026 00:31
Two adopter-facing artifacts that close out Phase 6b's user-facing
surface:

  - docs/deploy/migrating-to-hyperframes-lambda.mdx — side-by-side
    concept mapping for users coming from another one-command-deploy
    video renderer. Covers the verb mapping (deploy/render/progress/
    destroy/sites/policies), composition format (plain HTML vs JSX),
    render config, and a handful of intentional differences (no HDR
    in distributed mode, no webm, gpu-mode=software requirement,
    fail-closed font fetch, local stack-state files, narrow-after-
    first-deploy IAM pattern). Closes with a migration checklist.
    Per repo convention, no competitor framework is named anywhere
    in the source — adopters self-identify.

  - examples/k8s-jobs/Dockerfile.example + README.md — reference
    Dockerfile for adopters who want to run distributed renders
    outside AWS Lambda. Bakes Node 22 + chrome-headless-shell +
    ffmpeg + the producer source. Deliberately not published to
    a registry; adopters build it themselves so Chrome / ffmpeg /
    producer versions stay pinned to the checkout they audited.
    The README documents the typical K8s Jobs orchestration shape
    that points adopters at packages/aws-lambda/src/handler.ts as
    the reference adapter.

Migration guide registered under the existing Deploy group in
docs.json. .gitignore extended to negate the new examples/k8s-jobs/
path the same way examples/aws-lambda/ is negated.

No source code changes.
@jrusso1020 jrusso1020 force-pushed the docs-lambda-migration branch from 5be0bad to 1673e46 Compare May 17, 2026 00:51
@jrusso1020 jrusso1020 force-pushed the docs-lambda-deploy branch from 8d6ffe5 to 0ded0c0 Compare May 17, 2026 00:51
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.

3 participants