部署到 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