部署到 Cloudflare

本頁內容

Cloudflare Workers 為 EmDash 提供快速、全球分佈的執行環境。本指南介紹如何使用 D1 作為資料庫、R2 作為媒體儲存進行部署。

前提條件

  • Cloudflare 帳戶
  • 已安裝 Wrangler CLI(npm install -g wrangler
  • 已透過 wrangler login 登入 Cloudflare

建立資源

1. 建立 D1 資料庫

wrangler d1 create emdash-db

記下輸出中的 database_id

2. 建立 R2 儲存桶

wrangler r2 bucket create emdash-media

3. 建立 wrangler.jsonc

在專案根目錄建立 wrangler.jsonc

{
	"$schema": "node_modules/wrangler/config-schema.json",
	"name": "my-emdash-site",
	"compatibility_date": "2025-01-15",
	"compatibility_flags": ["nodejs_compat"],

	"d1_databases": [
		{
			"binding": "DB",
			"database_name": "emdash-db",
			"database_id": "your-database-id",
		},
	],

	"r2_buckets": [
		{
			"binding": "MEDIA",
			"bucket_name": "emdash-media",
		},
	],
}

配置 EmDash

更新 Astro 配置以使用 D1 和 R2:

import { defineConfig } from "astro/config";
import cloudflare from "@astrojs/cloudflare";
import emdash from "emdash/astro";
import { d1, r2 } from "@emdash-cms/cloudflare";

export default defineConfig({
	output: "server",
	adapter: cloudflare(),
	integrations: [
		emdash({
			database: d1({ binding: "DB" }),
			storage: r2({ binding: "MEDIA" }),
		}),
	],
});

執行遷移

生成並應用資料庫架構。

1. 匯出架構 SQL

npx emdash init --database ./data.db

2. 將遷移應用到 D1

wrangler d1 migrations apply emdash-db

若沒有遷移檔案,可直接應用核心架構:

wrangler d1 execute emdash-db --file=./node_modules/emdash/migrations/0001_core.sql

部署

部署到 Cloudflare Workers:

wrangler deploy

站點將位於 https://my-emdash-site.<your-subdomain>.workers.dev

讀取副本

對於全球分佈的站點,可啟用 D1 讀取複製,將讀查詢路由到附近的副本,而不是始終訪問主資料庫,從而顯著降低遠離主區域的訪客延遲。

emdash({
	database: d1({
		binding: "DB",
		session: "auto",
	}),
	storage: r2({ binding: "MEDIA" }),
}),

還需要在 Cloudflare 控制檯或透過 REST API 為 D1 資料庫本身啟用讀取複製。

會話模式與基於書籤的一致性說明見 資料庫選項 — 讀取副本

自定義域名

在 Cloudflare 控制檯新增自定義域名:

  1. 開啟 Workers & Pages > 你的 Worker
  2. 點選 Custom Domains > Add Custom Domain
  3. 輸入域名並按 DNS 說明操作

R2 公開訪問

若要從 R2 直接提供媒體(推薦,效能更好):

  1. 在 Cloudflare 控制檯進入 R2 > 你的儲存桶
  2. 開啟 Settings > Public access
  3. 啟用公開訪問並記下公開 URL
  4. 更新儲存配置:
storage: r2({
  binding: "MEDIA",
  publicUrl: "https://pub-xxx.r2.dev"
}),

Cloudflare Access 認證

若組織使用 Cloudflare Access,可將其作為身份提供方替代通行金鑰,與現有 IdP 實現 SSO。

emdash({
  database: d1({ binding: "DB" }),
  storage: r2({ binding: "MEDIA" }),
  auth: access({
    teamDomain: "myteam.cloudflareaccess.com",
    audience: "your-app-audience-tag",
    roleMapping: {
      "Admins": 50,
      "Editors": 40,
    },
  }),
}),

完整配置選項見 認證指南

環境變數

EmDash 需要若干金鑰用於認證與預覽功能。

必需金鑰

變數用途
EMDASH_AUTH_SECRET簽名會話 Cookie 與認證令牌。生產環境必需。
EMDASH_PREVIEW_SECRET簽名草稿預覽 URL。預覽功能必需。

生成安全金鑰:

npx emdash auth secret

透過 Wrangler 設定金鑰:

wrangler secret put EMDASH_AUTH_SECRET
wrangler secret put EMDASH_PREVIEW_SECRET

在配置中可透過 import.meta.env 或 Cloudflare env 繫結訪問環境變數。

預覽部署

部署預覽分支:

wrangler deploy --env preview

wrangler.jsonc 中新增環境段:

{
	"env": {
		"preview": {
			"d1_databases": [
				{
					"binding": "DB",
					"database_name": "emdash-db-preview",
					"database_id": "your-preview-db-id",
				},
			],
		},
	},
}

故障排除

“D1 binding not found”

確認 wrangler.jsonc 中的繫結名稱與資料庫配置一致:

// 須與 d1({ binding: "DB" }) 一致
"binding": "DB"

“R2 binding not found”

確認 R2 儲存桶已正確繫結:

// 須與 r2({ binding: "MEDIA" }) 一致
"binding": "MEDIA"

遷移錯誤

D1 遷移透過 Wrangler 執行,而非於執行階段。若出現架構錯誤:

  1. 檢查遷移是否已應用:wrangler d1 migrations list emdash-db
  2. 必要時重新應用:wrangler d1 migrations apply emdash-db