Cloudflare Containers
使用 Cloudflare Workers 和 Containers 部署 Remotion 伺服器端渲染的完整指南,含 wrangler.toml 設定與 R2 儲存整合。
Cloudflare Containers
Cloudflare Containers 是一個 Beta 階段的平台,可從 Cloudflare Worker 函式呼叫 Docker 容器,讓你在 Cloudflare 的全球邊緣網路上執行 Remotion 渲染工作。需要付費的 Workers 方案。
架構概覽
Cloudflare Containers 的渲染流程如下:
- 客戶端向 Cloudflare Worker 發送渲染請求
- Worker 函式驗證請求並啟動 Container 實例
- Container 執行 Remotion 渲染(包含 Chrome 和 FFmpeg)
- 渲染完成的影片儲存至 Cloudflare R2 Bucket
- Worker 回傳影片的存取 URL 給客戶端
前置需求
- 付費的 Cloudflare Workers 方案(Free 方案不支援 Containers)
- 已安裝 Wrangler CLI
- 已安裝 Docker
- Cloudflare R2 Bucket(用於儲存渲染輸出)
安裝 Wrangler CLI
npm install -g wrangler
wrangler login快速開始
複製官方示範存放庫:
git clone https://github.com/remotion-dev/cloudflare-containers-demo
cd cloudflare-containers-demo
npm installwrangler.toml 設定
以下是完整的 wrangler.toml 設定範例,涵蓋 Worker 和 Container 的配置:
name = "remotion-renderer"
main = "src/worker.ts"
compatibility_date = "2024-03-01"
compatibility_flags = ["nodejs_compat"]
# Container 設定
[containers]
image = "your-dockerhub-username/remotion-renderer:latest"
max_instances = 10
# R2 Bucket 綁定(用於儲存渲染輸出)
[[r2_buckets]]
binding = "OUTPUT_BUCKET"
bucket_name = "remotion-renders"
# 環境變數
[vars]
MAX_RENDER_DURATION_SECONDS = "300"
OUTPUT_FORMAT = "mp4"
# 生產環境設定
[env.production]
name = "remotion-renderer-prod"
[env.production.containers]
image = "your-dockerhub-username/remotion-renderer:latest"
max_instances = 50
[[env.production.r2_buckets]]
binding = "OUTPUT_BUCKET"
bucket_name = "remotion-renders-prod"CPU 與記憶體設定
[containers]
image = "your-dockerhub-username/remotion-renderer:latest"
max_instances = 10
# 指定 Container 資源(視帳號配額而定)
[containers.resources]
vcpu = 2
memory_mb = 4096Worker 函式實作
interface Env {
CONTAINER: Container;
OUTPUT_BUCKET: R2Bucket;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
if (request.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 });
}
const { compositionId, inputProps } = await request.json<{
compositionId: string;
inputProps: Record<string, unknown>;
}>();
// 啟動 Container 並執行渲染
const container = await env.CONTAINER.newUniqueId();
const stub = env.CONTAINER.get(container);
const renderResponse = await stub.fetch("http://container/render", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ compositionId, inputProps }),
});
if (!renderResponse.ok) {
const error = await renderResponse.text();
return Response.json({ error }, { status: 500 });
}
const { outputPath } = await renderResponse.json<{ outputPath: string }>();
// 從 Container 取得渲染結果並上傳至 R2
const videoResponse = await stub.fetch(`http://container/output/${outputPath}`);
const videoBuffer = await videoResponse.arrayBuffer();
const objectKey = `renders/${crypto.randomUUID()}.mp4`;
await env.OUTPUT_BUCKET.put(objectKey, videoBuffer, {
httpMetadata: { contentType: "video/mp4" },
});
const publicUrl = `https://pub-your-account-id.r2.dev/${objectKey}`;
return Response.json({ url: publicUrl });
},
};Dockerfile 設定
FROM node:18-slim
# 安裝 Chromium 依賴
RUN apt-get update && apt-get install -y \
chromium \
ffmpeg \
fonts-noto-cjk \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV CHROME_PATH=/usr/bin/chromium
EXPOSE 8080
CMD ["node", "dist/server.js"]部署
# 建置並推送 Docker 映像
docker build -t your-dockerhub-username/remotion-renderer:latest .
docker push your-dockerhub-username/remotion-renderer:latest
# 部署至 Cloudflare
wrangler deploy
# 部署至生產環境
wrangler deploy --env production限制與注意事項
Cloudflare Containers 目前仍在 Beta 階段,官方示範是概念驗證專案,尚未具備生產就緒的狀態。目前未考慮以下面向:
- 無認證機制:示範不包含 API 金鑰或 JWT 驗證
- 無渲染佇列:並行請求可能互相競爭資源
- 無速率限制:容易受到濫用攻擊
- 無進度回報:客戶端無法得知渲染進度
- 錯誤不會傳播:渲染失敗時客戶端收不到詳細錯誤訊息
- 影片以隨機名稱儲存:缺乏系統化的命名規則
生產環境建議實作
在正式上線前,應補充以下功能:
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// API 金鑰驗證
const authHeader = request.headers.get("Authorization");
if (authHeader !== `Bearer ${env.API_SECRET}`) {
return Response.json({ error: "未授權" }, { status: 401 });
}
// 速率限制(搭配 Cloudflare Rate Limiting 規則設定)
// 佇列管理(搭配 Cloudflare Queues)
// 進度回報(搭配 Durable Objects 或 WebSocket)
// ... 渲染邏輯
},
};費用考量
使用 Cloudflare Containers 的費用由以下部分組成:
- Workers 執行時間費用(每百萬次請求計費)
- Container 運算費用(依 vCPU 和記憶體用量計費)
- R2 儲存費用(每 GB/月)
- R2 資料傳輸費用(Class A/B 操作)
請查閱 Cloudflare Containers 定價 和 R2 定價 了解最新費率。
相關資源
- Cloudflare Containers 文件 — 官方平台文件
- Wrangler CLI 文件 — 部署工具說明
- Cloudflare R2 — 物件儲存服務
- 示範原始碼 — Remotion 整合示範
- Azure Container Apps — 另一個容器渲染選項
- 伺服器端渲染 — 伺服器端渲染概覽