Cloudflare Workers 为 EmDash 提供快速、全球分布的运行时。本指南介绍如何使用 D1 作为数据库和 R2 作为媒体存储进行部署。
前置条件
- 一个 Cloudflare 账户
- 已安装 Wrangler CLI(
npm install -g wrangler) - 已通过 Cloudflare 身份验证(
wrangler login)
配置绑定
在项目根目录创建包含 D1 和 R2 绑定的 wrangler.jsonc。如果资源尚不存在,Wrangler 会在首次部署时自动配置这两个资源。
{
"$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",
},
],
"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" }),
}),
],
});
首次启动
数据库迁移会在部署后的第一个请求时自动运行,如果有新内容需要应用,则会在每次后续启动时运行。
如果数据库为空(没有集合)且设置向导尚未完成,EmDash 也会在首次启动时应用种子文件。种子文件在构建时从 .emdash/seed.json、package.json#emdash.seed 中的路径或 seed/seed.json 读取 —— 以首先找到的为准 —— 并内联到包中。如果都不存在,则使用内置的默认种子。针对现有数据库的后续部署会保持其内容不变。
部署
部署到 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 仪表板中添加自定义域名:
- 转到 Workers & Pages > 您的 worker
- 点击 Custom Domains > Add Custom Domain
- 输入您的域名并按照 DNS 设置说明操作
公开 R2 访问
要直接从 R2 提供媒体服务(推荐用于性能):
- 在 Cloudflare 仪表板中,转到 R2 > 您的存储桶
- 点击 Settings > Public access
- 启用公开访问并记下公开 URL
- 更新存储配置:
storage: r2({
binding: "MEDIA",
publicUrl: "https://pub-xxx.r2.dev"
}),
Cloudflare Access 身份验证
如果您的组织使用 Cloudflare Access,您可以将其用作身份验证提供者而不是密钥,通过现有的身份提供者提供单点登录。以下配置启用它:
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_ENCRYPTION_KEY 是用于加密静态插件密钥(webhook 令牌、Turnstile 密钥等)的密钥。密钥在启动时进行验证;一旦启用,插件密钥加密就会使用它。在每次部署时设置它,以便在不更改配置的情况下保护密钥。
密钥由您提供,永远不会存储在数据库中;只存储加密的密文。丢失它意味着丢失用它加密的每个密钥。
使用以下命令生成密钥并将其存储为 Worker 密钥:
npx emdash secrets generate
wrangler secret put EMDASH_ENCRYPTION_KEY
可选:稳定值覆盖
EmDash 会自动生成预览 HMAC 密钥和评论者 IP 哈希盐,并在首次使用时将它们持久化到数据库中。下面的环境变量是用于需要自己固定值的情况的覆盖 —— 例如,当单独进程中的预览 Worker 需要与主站点共享密钥时。
| 变量 | 用途 |
|---|---|
EMDASH_PREVIEW_SECRET | 自动生成的预览 HMAC 密钥的覆盖。 |
EMDASH_IP_SALT | 自动生成的评论者 IP 哈希盐的覆盖。 |
EMDASH_AUTH_SECRET | 可选。如果设置,它将用作 IP 盐源(除非也设置了 EMDASH_IP_SALT,后者优先),为已经依赖它的安装保持评论者 IP 哈希的稳定。对于新部署,请保持未设置状态。 |
使用 import.meta.env 或 Cloudflare env 绑定在配置中访问环境变量。
预览部署
部署预览分支:
wrangler deploy --env preview
在 wrangler.jsonc 中添加环境部分:
{
"env": {
"preview": {
"d1_databases": [
{
"binding": "DB",
"database_name": "emdash-db-preview",
},
],
},
},
}
故障排除
”D1 binding not found”
验证 wrangler.jsonc 中的绑定名称是否与数据库配置匹配:
// Must match: d1({ binding: "DB" })
"binding": "DB"
“R2 binding not found”
检查 R2 存储桶是否正确绑定:
// Must match: r2({ binding: "MEDIA" })
"binding": "MEDIA"
迁移错误
如果您看到模式错误,请跟踪 Worker 日志(wrangler tail)并重现错误以捕获底层消息 —— 然后使用该输出提交问题。