Files
hyperframes/docs/deploy/gcp-cloud-run.mdx
Miguel Ángel 992df8b203 perf(cloud): move project bytes once through shared content storage (#5772)
* perf(producer): distributed chunks download only the videos they show

A project video under compiled/ that chunks extract their own frames from
now goes only to the chunks that show it, like video-sources/ files. A
chunk skips the readiness wait for a deferred video it does not show, so
it no longer logs media_load_failed for a file it was never given.

* fix(producer): cloud site uploads pack the files their id hashes, symlinks included

* perf(aws-lambda): chunks read only the byte ranges of a video they need

A chunk that extracts its own frames from a deferred project video now
reads it from S3 by byte range through a short-lived pre-signed URL,
instead of downloading and hashing the whole object first. S3 attests the
object's stored SHA-256 before the URL is signed; every other artifact is
still downloaded and verified as before.

* perf(aws-lambda): upload project files once to a shared content-addressed area

* chore(producer): keep planV2 comment share at the base level

* fix(engine): verify the TLS certificate of https video inputs and never surface their signed query

* fix(aws-lambda): renders re-upload a site's expired files instead of failing

* perf(aws-lambda): the plan step probes project videos in place instead of downloading them

* fix(engine): https video reads reconnect and time out, and redaction covers wrapped causes

Signed-URL reads now pass -rw_timeout, -reconnect and -reconnect_delay_max (both Lambda builds accept them) and ffmpeg also -reconnect_on_network_error, so a transient S3 error or a stalled read fails fast or recovers instead of waiting out the process timeout. Query redaction now descends into error.cause.

* fix(aws-lambda): share entry bundles and ratchet package budget

* fix(aws-lambda): site ids uploaded before files.json still render

A site id from an earlier sites create has only sites/<id>/project.tar.gz.
renderToLambda now falls back to that tarball, which the plan step still
reads, and when neither key exists it fails before starting with both keys
named and the fix (run sites create again).

* fix(aws-lambda): renders fail before upload on a stack too old to read sites

A stack deployed before files.json sites untars the site file in its plan
step and fails after four retries. renderToLambda now reads the state
machine definition first and stops with STACK_TOO_OLD and the redeploy
command when the plan task does not list SITE_MANIFEST_INVALID, which new
SAM and CDK stacks now treat as terminal. The README's upgrade section
drops the planProtocol v1 fallback, which hits the same failure.

* docs(aws-lambda): document shared content storage and the upgrade path

The deploy guide still described the tarball HeadObject short-circuit. It
now covers the cas/sha256/ store and its 30-day lifecycle rule, the
STACK_TOO_OLD, SITE_FILES_MISSING and SITE_NOT_FOUND errors, that old site
ids keep working, and that every project uploads once more after the
upgrade. A test keeps a troubleshooting entry for each pre-submit error.

* fix(producer): chunks log each video they read by URL, without its query

A chunk reading a video straight from the bucket left no trace in its log.
It now logs one line per remote source with the path and the URL minus its
query string, so signatures never reach the log.

* fix(engine): ffmpeg errors never keep part of a signed URL's query

A process's stderr tail was trimmed before its URLs were redacted, so a
cut inside a signed URL left a query fragment the URL pattern no longer
matched, and the fragment reached the error. The stderr tail is now
redacted before every trim, and the redactor also strips a signing
parameter cut off from its URL.

* fix(aws-lambda): comments name the site manifest instead of a file path

* fix(engine): stderr redaction survives chunk splits, and every ffmpeg spawn uses it

The stderr tail was redacted on each chunk and then cut, so once a cut
severed a long URL's scheme, the rest of its signature in the next chunk
matched neither pattern. The tail is now kept raw with 2x slack and
redacted only when the text is produced, then cut to size. The unused
producer audioExtractor (its own spawn, unredacted stderr) is deleted and
the parity harness's PCM decode goes through ManagedChildProcess; a test
fails on any ffmpeg/ffprobe spawn in engine, producer or aws-lambda that
does not.

* chore(producer): record the audioExtractor deletion as intended

* fix(engine): drop a signature fragment the stderr tail cut from its URL

The raw tail is kept at twice the cap, but that cut can itself land inside a
signature, and when redaction shrinks the rest below the cap the fragment
survived. After a cut, the severed token is dropped before redaction.

* refactor(engine): name the severed-token drop instead of commenting it

* test(engine): a cut-off URL leaves nothing behind; aws-lambda size budget to measured

* fix(producer): chunk URL-read tests use main's frame list; producer size budget to measured

* chore(producer): size budget at the measured size, no headroom

* chore(producer): size budget back to measured x1.05, the check's own rule
2026-10-19 19:23:51 +00:00

125 lines
3.7 KiB
Plaintext

---
title: "Google Cloud Run"
description: "Deploy distributed HyperFrames rendering to Cloud Run, Cloud Workflows, and Google Cloud Storage."
---
Use this path when renders must run in your Google Cloud account. A Cloud
Workflow plans the render, sends chunks to Cloud Run in parallel, and assembles
the result in Google Cloud Storage.
```text
Cloud Workflow: Plan → Render chunks in parallel → Assemble
↓
Cloud Run service
↓
GCS
```
For a hosted render without infrastructure ownership, use
[HyperFrames Cloud](/deploy/cloud). For a small preview application and render
endpoint, use a [hosted template](/guides/deploy).
## Prerequisites
- A Google Cloud project with billing enabled
- `gcloud` authenticated for that project
- Terraform 1.5 or newer
- Cloud Build access, or an existing compatible container image
- `@hyperframes/gcp-cloud-run` installed alongside the CLI
The CLI can build the renderer automatically when it runs from a HyperFrames
repository checkout. Outside the repository, pass an image built from
`packages/gcp-cloud-run/Dockerfile` with `--image`.
## Deploy
```bash
hyperframes cloudrun deploy --project my-gcp-project
```
The command enables the required Google Cloud APIs, builds and pushes the
renderer when needed, applies the bundled Terraform module, and stores the
resulting bucket, service URL, and workflow name in `~/.hyperframes/`.
The default region is `us-central1`. Machine and scaling controls include
`--region`, `--cpu`, `--memory`, `--max-instances`, and `--timeout`.
## Render
Width and height describe the authored canvas. Use `--output-resolution` when
the encoded result should be supersampled without changing the layout.
```bash
hyperframes cloudrun render ./my-project \
--width 1920 \
--height 1080 \
--wait
```
The command accepts the same template variables used by local and AWS renders:
```bash
hyperframes cloudrun render ./card-template \
--width 1920 \
--height 1080 \
--variables '{"name":"Ada"}' \
--wait
```
Supported distributed outputs are MP4, MOV, WebM, and PNG sequences. MP4 can
use H.264 or H.265. Distributed rendering is currently SDR-only.
## Reuse an upload
Projects are content-addressed. Upload an unchanged project once, then reuse
its site ID for later renders. Site IDs from earlier versions keep working, but
the ID scheme changed, so each project uploads once more under a new ID:
```bash
hyperframes cloudrun sites create ./my-project
```
Use `render-batch` with a JSONL file when one template needs many sets of
variables:
```bash
hyperframes cloudrun render-batch ./card-template \
--batch ./recipients.jsonl \
--width 1920 \
--height 1080 \
--max-concurrent 10
```
Each JSONL row contains an output key and optional variables:
```json
{"outputKey":"renders/ada.mp4","variables":{"name":"Ada"}}
```
## Progress and teardown
Without `--wait`, a render returns its workflow execution name immediately.
```bash
hyperframes cloudrun progress <execution-name>
hyperframes cloudrun destroy --project my-gcp-project
```
`destroy` removes the Terraform-managed stack and its render bucket. Download
anything that must be retained before running it.
## Programmatic use
`@hyperframes/gcp-cloud-run/sdk` exposes `deploySite`, `renderToCloudRun`, and
`getRenderProgress` for Node backends. The package also exports the Terraform
module and HTTP handler used by the deployed service.
See the [GCP package reference](/packages/gcp-cloud-run) for the SDK contract
and the complete infrastructure shape.
## Related topics
- [Use the Google Cloud Run package](/packages/gcp-cloud-run)
- [Choose another rendering path](/deploy/overview)
- [Compare with AWS Lambda](/deploy/aws-lambda)