Remotion LabRemotion Lab
伺服器端渲染Vercel 沙盒部署

Vercel 沙盒部署

在 Vercel Serverless Functions 和 Sandbox 環境上部署 Remotion 伺服器端渲染的完整指南,含限制說明與輕量渲染使用情境。

Vercel 沙盒部署

Vercel 提供兩種方式來執行 Remotion 伺服器端渲染:傳統的 Serverless Functions 以及較新的 Vercel Sandbox。本文涵蓋兩者的設定方式、限制與適用情境。

Vercel Serverless Functions 的限制

在標準 Vercel Serverless Functions 上執行 Remotion 渲染有嚴格的資源上限。了解這些限制有助於判斷 Vercel 是否適合你的使用情境。

逾時限制

方案最長執行時間
Hobby10 秒
Pro60 秒(可設定至 300 秒)
Enterprise900 秒

Remotion 渲染一段 10 秒、30fps 的影片可能需要 1–3 分鐘,視複雜度而定。因此,標準 Serverless Functions 不適合渲染完整影片,但可用於渲染靜態截圖(Still)或極短片段。

記憶體限制

Vercel Serverless Functions 的記憶體上限為 3,009 MB。Remotion 渲染器需要啟動 Chromium 瀏覽器,本身就佔用約 400–600 MB。在複雜構圖或包含大量資產的情況下,可能會觸及此上限。

不建議使用 Serverless Functions 渲染影片的原因

  • 逾時風險高,長影片幾乎必然超時
  • 無法使用分散式渲染(Lambda 的分塊並行機制)
  • Cold start 時間(約 3–8 秒)會被計入執行時間
  • 無法持久儲存渲染進度或中繼狀態

Vercel Sandbox(推薦方案)

Vercel Sandbox 是專為長時間執行工作負載設計的環境,每次渲染會啟動一個短暫的 Linux 虛擬機,可完整存取 Remotion 渲染器,無需管理 Lambda 或 AWS 基礎架構。

Sandbox 配額上限

方案逾時上限並發渲染數
Hobby45 分鐘10 個同時渲染
Pro / Enterprise5 小時2,000 個同時渲染

快速開始

使用官方模板建立專案:

npx create-video@latest --template vercel

或透過 Vercel 模板市場一鍵部署:Remotion on Vercel 模板

部署後,在 Vercel 儀表板的「Storage」下建立新的 Blob 儲存區並連接至專案,重新部署使變更生效。

@remotion/vercel 套件

@remotion/vercel 套件提供在 Vercel Sandbox 上渲染 Remotion 影片的程式化 API。

安裝

npm install @remotion/vercel

主要 API

API說明
createSandbox()建立已安裝 Remotion 的沙盒實例
addBundleToSandbox()將 Remotion bundle 複製至沙盒
renderMediaOnVercel()在沙盒中渲染影片
renderStillOnVercel()在沙盒中渲染靜態圖片
uploadToVercelBlob()將渲染結果上傳至 Vercel Blob

基本使用範例

app/api/render/route.ts
import {
  addBundleToSandbox,
  createSandbox,
  renderMediaOnVercel,
  uploadToVercelBlob,
} from "@remotion/vercel";
import { bundle } from "@remotion/bundler";
import { selectComposition } from "@remotion/renderer";
 
export const maxDuration = 300; // 秒,需要 Pro 方案
 
export async function POST(request: Request) {
  const { compositionId, inputProps } = await request.json();
 
  // 1. 打包 Remotion 專案
  const bundleLocation = await bundle({
    entryPoint: "./src/index.ts",
  });
 
  // 2. 建立沙盒並上傳 bundle
  const sandbox = await createSandbox();
  const sandboxBundlePath = await addBundleToSandbox(sandbox, bundleLocation);
 
  // 3. 解析組合
  const composition = await selectComposition({
    serveUrl: sandboxBundlePath,
    id: compositionId,
    inputProps,
  });
 
  // 4. 渲染影片
  const outputPath = await renderMediaOnVercel({
    sandbox,
    composition,
    serveUrl: sandboxBundlePath,
    inputProps,
    codec: "h264",
  });
 
  // 5. 上傳至 Vercel Blob
  const { url } = await uploadToVercelBlob(sandbox, outputPath);
 
  return Response.json({ url });
}

適合 Vercel 的使用情境

雖然 Vercel 不適合重度渲染工作,以下情境相當適合:

  • 靜態截圖(Still)渲染:單一畫格渲染通常在數秒內完成
  • 短片段預覽:5 秒以下的預覽影片
  • 原型開發:快速驗證渲染邏輯,無需配置 AWS
  • 低頻渲染服務:每日渲染次數不多的應用

部署注意事項

安全提醒:官方模板不包含速率限制或快取功能。在公開應用程式前,請實作這些功能,並設定 Vercel Spend Management 以控制成本。沙盒快照、已渲染的影片和其他 Vercel Blob 資料會無限期保存——不再需要時請予以刪除。

建議的生產環境配置

app/api/render/route.ts(含速率限制)
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
 
const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(5, "1 m"), // 每分鐘最多 5 次請求
});
 
export async function POST(request: Request) {
  const ip = request.headers.get("x-forwarded-for") ?? "anonymous";
  const { success } = await ratelimit.limit(ip);
 
  if (!success) {
    return Response.json({ error: "請求過於頻繁,請稍後再試" }, { status: 429 });
  }
 
  // ... 渲染邏輯
}

與其他方案比較

方案設定複雜度渲染速度適合長影片費用模型
Vercel Sandbox是(Sandbox)按使用量
AWS Lambda快(分散式)按使用量
Docker 自管視硬體而定固定費用

相關資源