Miraiclip SDK

Google Cloud

Run the render worker on Cloud Run or a Compute Engine VM.

Both options run the render worker image.

OptionPick it for
Cloud RunThe default. One job per instance, scales to zero, no servers to manage
Compute EngineOne machine with a fixed cost, jobs longer than 60 minutes, or GPUs

The commands below use the gcloud CLI. Set your project and region once:

export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export IMAGE=$REGION-docker.pkg.dev/$PROJECT_ID/miraiclip/render-worker:latest

gcloud services enable run.googleapis.com artifactregistry.googleapis.com secretmanager.googleapis.com

Push the image to Artifact Registry

gcloud artifacts repositories create miraiclip --repository-format=docker --location=$REGION
gcloud auth configure-docker $REGION-docker.pkg.dev

docker build --platform linux/amd64 -t $IMAGE .
docker push $IMAGE

The image is x86-64 only (Google Chrome has no Linux Arm build), so pick x86-64 machine types for VMs, not Arm (Axion, Tau T2A).

Store the worker's token in Secret Manager, and let the runtime service account read it (Cloud Run and Compute Engine use the Compute Engine default service account unless you choose another):

openssl rand -hex 32 | gcloud secrets create render-token --data-file=-

export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
gcloud secrets add-iam-policy-binding render-token \
  --member=serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
  --role=roles/secretmanager.secretAccessor

Cloud Run

gcloud run deploy miraiclip-render-worker \
  --image $IMAGE \
  --region $REGION \
  --cpu 2 \
  --memory 4Gi \
  --concurrency 1 \
  --timeout 3600 \
  --max-instances 20 \
  --execution-environment gen2 \
  --cpu-boost \
  --set-secrets RENDER_TOKEN=render-token:latest \
  --allow-unauthenticated
FlagWhy
--concurrency 1A worker renders one job at a time. Cloud Run sends each job to a free instance and starts new ones as jobs arrive
--timeout 3600Jobs can run up to 60 minutes, the Cloud Run maximum. Split longer exports with renderDistributed
--cpu 2 --memory 4GiEnough for 1080p. For 4K, use --cpu 4 --memory 8Gi
--max-instancesA ceiling on cost: at most this many jobs render at once
--execution-environment gen2Full Linux compatibility for Chrome
--cpu-boostMore CPU while an instance starts, so cold starts are shorter
--allow-unauthenticatedCloud Run lets requests through; the worker checks RENDER_TOKEN itself

Cloud Run's file system lives in memory: the output a job writes to /tmp counts against --memory. Leave room for your largest output on top of Chrome.

Instead of building locally, gcloud run deploy miraiclip-render-worker --source . builds the Dockerfile with Cloud Build and deploys it in one step.

Check it:

URL=$(gcloud run services describe miraiclip-render-worker --region $REGION --format='value(status.url)')
curl $URL/healthz
# ok

Render

import { httpRunner, renderDistributed } from "@miraiclip/server-export";

const runner = httpRunner({
  endpoints: "https://miraiclip-render-worker-<hash>.<region>.run.app",
  headers: { authorization: `Bearer ${process.env.RENDER_TOKEN}` },
  concurrency: 16, // jobs in flight; Cloud Run starts an instance for each, up to --max-instances
});

await renderDistributed(doc, { format: "mp4", out: "final.mp4", runner });

Or send single jobs with fetch, as in Send a render job.

Private services

To keep the service off the public internet, deploy with --no-allow-unauthenticated and call it with a Google identity token. Cloud Run reads the token from X-Serverless-Authorization, which leaves Authorization for the worker's own RENDER_TOKEN:

curl -X POST $URL \
  -H "X-Serverless-Authorization: Bearer $(gcloud auth print-identity-token --audiences=$URL)" \
  -H "Authorization: Bearer $RENDER_TOKEN" \
  -H "content-type: application/json" \
  --data @job.json -o final.mp4

The caller's service account needs roles/run.invoker on the service. Identity tokens expire after an hour, so refresh them for long batches.

Compute Engine

One VM running the container. Use a compute-optimized x86-64 type, such as c3-standard-4 (4 vCPU, 16 GB):

gcloud compute instances create miraiclip-render-worker \
  --zone ${REGION}-a \
  --machine-type c3-standard-4 \
  --image-family debian-12 --image-project debian-cloud \
  --boot-disk-size 50GB \
  --scopes cloud-platform

gcloud compute ssh miraiclip-render-worker --zone ${REGION}-a

On the VM, set REGION and IMAGE as above, then:

sudo apt-get update && sudo apt-get install -y docker.io
sudo gcloud auth configure-docker $REGION-docker.pkg.dev

sudo docker run -d --name render-worker --restart unless-stopped \
  -p 8080:8080 \
  -e RENDER_TOKEN="$(gcloud secrets versions access latest --secret=render-token)" \
  $IMAGE

Put the VM behind a load balancer or a reverse proxy for HTTPS rather than opening port 8080 to the internet. To use more cores on one machine, run several containers on different ports, one per 2 vCPUs, and list them all in httpRunner's endpoints.

On this page