---
title: "在 Cloudflare Workers 上运行 Web 层"
description: "在 Cloudflare Workers 上运行精简版 Quire Web 层。"
image: "https://docs.quirelms.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.quirelms.com/zh-Hans/llms.txt
> Use this file to discover all available pages before exploring further.

# 在 Cloudflare Workers 上运行 Web 层

<span id="the-web-tier-on-cloudflare-workers"></span>

架构设计见 `docs/architecture/23-ops.md` 第 6 节。Workers 只运行精简版 Web 层。此部署目标不要求功能与完整版本一致（PRD 第 12 节）：启动时会明确指出并拒绝不支持的功能。

## 本版本状态 <!--quire:status-in-this-release-->

配置已经就绪（`apps/web/wrangler.jsonc`、`cloudflare-module` Nitro 预设、Hyperdrive 桥接层和启动检查）。Worker 需要使用 R2 的 S3 兼容存储（`QUIRE_STORAGE_DRIVER=s3`）、支持跨请求运行的实时驱动（`QUIRE_REALTIME_DRIVER=durable_objects` 或 `centrifugo`）、共享缓存（`QUIRE_CACHE_DRIVER=postgres` 或 `valkey`）以及 HTTP 电子邮件服务提供商。缺少其中任何一项，Worker 都会拒绝启动，并在日志中列出缺少的设置。Durable Objects 驱动通过 `apps/realtime-worker` 中的实时 Worker 提供服务（每个频道一个 Durable Object，用于扇出、在线状态和历史记录；每个人一个 Durable Object，用于检测断开连接）；请按下文部署，或改用 Centrifugo。

## 组件 <!--quire:the-pieces-->

| 组件 | 在 Cloudflare 上的运行位置 |
| --- | --- |
| `web` | 使用 `nodejs_compat` 的 Worker |
| Postgres | 外部数据库，通过 Hyperdrive 访问：`HYPERDRIVE` 用于应用角色，`REPORT_HYPERDRIVE` 用于同一物理数据库中的报告角色。Web 层启动时会分别将连接字符串复制到 `DATABASE_URL` 和 `QUIRE_REPORT_DATABASE_URL` |
| 文件 | 通过 S3 API 使用 R2（`S3_ENDPOINT=https://<account>.r2.cloudflarestorage.com`）；`FILES` 绑定用于连接存储桶 |
| 后台任务 | 需要与写入操作同时入队时，通过 Hyperdrive 使用 pg-boss。若在配套 worker 上设置 `QUIRE_QUEUE_DRIVER=cloudflare`，轻量任务（无序通知和 webhook 投递）会改用 Cloudflare Queues，因此不会为这些任务轮询 Postgres。配套 worker 会运行两种队列 |
| 实时通信 | 使用 Durable Objects 的实时 Worker，即 `apps/realtime-worker` |
| `worker`、`scheduler`、`collab`、`content`、ClamAV、Gotenberg、ffmpeg | 在配套容器主机上运行。Worker 无法运行这些服务 |
| 跟踪 | 在 `wrangler.jsonc` 中启用的 Workers 可观测性 |

`REPORT_HYPERDRIVE` 为 `HYPERDRIVE` 指定的物理数据库提供报告角色。如下一节所述，此部署目标不支持固定到其他物理数据库的租户。

## 此部署目标不支持的功能 <!--quire:what-this-target-cannot-do-->

启动时会一次列出所有问题并拒绝运行：

- **不支持 SMTP。**请在 `QUIRE_EMAIL_PROVIDER_CONFIG` 中设置 HTTP 服务提供商。
- **不支持本地磁盘。**`QUIRE_STORAGE_DRIVER` 必须指定对象存储。
- **不支持进程内实时通信或缓存。**Workers 请求之间不共享内存，因此设置 `QUIRE_REALTIME_DRIVER=inprocess` 或 `QUIRE_CACHE_DRIVER=memory` 会被拒绝。
- **Worker 中不支持 ClamAV、Gotenberg 或 ffmpeg。**如果在 Worker 上设置 `CLAMAV_URL`、`GOTENBERG_URL` 或 `FFMPEG_PATH`，系统会拒绝启动；请在配套 worker 上设置这些选项。
- **不支持使用专用数据库的组织。**Worker 的 Hyperdrive 绑定在部署时固定，因此使用自有数据库的组织会看到明确的“此处不可用”页面。请通过 Compose 或 Vercel 为其提供服务。

还有一项不会导致启动被拒绝，但必须了解：**Workers 不支持预渲染和增量静态再生成**，无论框架文档如何说明。所有路由都会针对每个请求单独渲染。

此部署目标中事务应尽可能短，且不要跨网络调用持有事务：连接返回连接池时 Hyperdrive 会重置会话状态，因此租户上下文必须按事务设置。

## 部署 <!--quire:deploying-->

1. 创建资源：
   ```sh
   bun run --bun wrangler hyperdrive create quire-app --connection-string="postgres://quire_app:...@db.example.com:5432/quire"
   bun run --bun wrangler hyperdrive create quire-report --connection-string="postgres://quire_report:...@db.example.com:5432/quire"
   bun run --bun wrangler r2 bucket create quire-files
   bun run --bun wrangler queues create quire-jobs
   ```
   将两个 Hyperdrive ID 填入 `apps/web/wrangler.jsonc`。
2. 使用 `bun run --bun wrangler secret put <NAME>` 设置密钥（在 `apps/web` 中运行）：`QUIRE_SECRET_KEY`、`QUIRE_MASTER_KEY`、`QUIRE_EMAIL_PROVIDER_CONFIG`、`S3_ACCESS_KEY_ID`、`S3_SECRET_ACCESS_KEY`、`QUIRE_COLLAB_SIGNING_KEY`、`QUIRE_REALTIME_WORKER_SECRET`。普通设置（`QUIRE_APP_ORIGIN`、`QUIRE_CONTENT_ORIGIN`、`QUIRE_PLATFORM_DOMAINS`、`QUIRE_DATABASE_ID`、`S3_ENDPOINT`、`S3_BUCKET`、`QUIRE_COLLAB_URL`）放入 `vars`。
3. 在 `apps/web` 中构建并部署：
   ```sh
   NITRO_PRESET=cloudflare-module bun run build
   bun run --bun wrangler deploy
   ```
4. 部署实时 Worker，配置与 Web 层相同的 `QUIRE_REALTIME_WORKER_SECRET`，并将其 token 密钥设为 `QUIRE_REALTIME_TOKEN_SECRET`（Web 层使用自己的 `QUIRE_REALTIME_TOKEN_SECRET` 为实时令牌签名；未设置时使用 `QUIRE_SECRET_KEY`，请按实际情况配置）。再将 Web 层的 `QUIRE_REALTIME_WORKER_URL` 设为该 Worker 的地址：
   ```sh
   cd apps/realtime-worker
   bun run --bun wrangler secret put QUIRE_REALTIME_WORKER_SECRET
   bun run --bun wrangler secret put QUIRE_REALTIME_TOKEN_SECRET
   bun run --bun wrangler deploy
   ```
5. 要通过 Cloudflare Queues 运行轻量任务，请为每个轻量队列创建一个队列，并在配套 worker 上设置以下配置（使用具有队列读取和写入权限的 API token）：
   ```sh
   bun run --bun wrangler queues create quire-events-notifications
   bun run --bun wrangler queues create quire-events-notifications-dead
   bun run --bun wrangler queues create quire-events-webhooks
   bun run --bun wrangler queues create quire-events-webhooks-dead
   ```
   设置 `QUIRE_QUEUE_DRIVER=cloudflare`、`CLOUDFLARE_ACCOUNT_ID`、`CLOUDFLARE_QUEUES_TOKEN`；如果前缀不是默认值，还要设置 `QUIRE_QUEUE_PREFIX`，默认值为 `quire-`。
6. 按照 [Vercel 指南](/zh-Hans/ops/vercel/)第 3 步运行配套主机。每次部署 Worker 前都要在此处运行迁移。

配置被拒绝时，运行 `bun run --bun wrangler tail` 会看到 “The web tier did not start on cloudflare”，后面列出需要更改的设置。

Source: https://docs.quirelms.com/zh-Hans/ops/cloudflare/index.mdx
