部署到 Cloudflare

本页内容

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.jsonpackage.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 仪表板中添加自定义域名:

  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,您可以将其用作身份验证提供者而不是密钥,通过现有的身份提供者提供单点登录。以下配置启用它:

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)并重现错误以捕获底层消息 —— 然后使用该输出提交问题。