Files
blog/blog-admin/wrangler.toml
T
zqlit 8f2eee1a38 fix(ssl): 注释掉 [limits] cpu_ms —— 免费版会直接拒绝部署
2026-10-06 实测 wrangler deploy 报错:
  X [ERROR] A request to the Cloudflare API (.../versions) failed.
    CPU limits are not supported for the Free plan. [code: 100328]

注意是「整个部署失败」而非「忽略该字段」,所以 Free plan 下必须注释。
同时记下影响:免费版 CPU 硬顶 10ms,ACME 签发(ECDSA 签名 + 手写 DER CSR)
跑不起来 —— 签发/续期链路需要 Workers Paid;探针/自检/查询不受影响。

升级 Paid 后放开注释即可(cron 默认 30s,Paid 可到 5min)。
2026-10-06 17:06:51 +08:00

163 lines
8.8 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name = "artalk-cf"
main = "src/index.ts"
compatibility_date = "2026-07-24"
# ★ 证书探针需要 node:tls —— 只有它能在 Workers 里拿到**对端证书正文**
# (`cloudflare:sockets` 的 Socket 接口没有 getPeerCertificate,
# 实测线上只能确认「可达」但读不到 notAfter/SAN/issuer,那样证书管家等于瞎的)。
# 2026-08-04 之后的 compatibility_date 才默认带 nodejs_compat,
# 本项目定在 2026-07-24,所以必须显式打开这个 flag。
compatibility_flags = ["nodejs_compat"]
# ---------------------------------------------------------------------------
# ★ Workers Cache —— 缓存 Worker 自己生成的响应(无需回源 fetch)
#
# 为什么必须开:Worker 位于 zone 缓存之前("Workers sits in front of cache"),
# 所以 **zone 级 Cache Rules / Page Rules 对 Worker 响应完全无效**。
# 想让 /api/favicon 这类「Worker 直接返回」的响应被边缘缓存、从而不再执行
# Worker(省 KV 读 + 省 Worker 请求),唯一正解是这个 [cache] enabled。
#
# 生效条件(缺一不可):
# 1. 这里是 fetch 处理器(scheduled 等不参与缓存)
# 2. 响应带可缓存的 Cache-Control(本项目已带 s-maxage=86400)
# 3. 只缓存 GET/HEAD;带 Set-Cookie 的响应自动绕过
# 验证:连续两次 curl -I,应依次看到 cf-cache-status: MISS → HIT
# ---------------------------------------------------------------------------
[cache]
enabled = true
# ---------------------------------------------------------------------------
# D1 (必须) 创建:npx wrangler d1 create artalk-cf
# 然后把返回的 database_id 填到下面
# ---------------------------------------------------------------------------
[[d1_databases]]
binding = "DB"
database_name = "artalk-cf"
database_id = "78140776-2bfd-439a-8b05-c3eebe5d5b47"
# ---------------------------------------------------------------------------
# KV —— RSS 订阅数据(rss-robot 合并进来;KV 与 D1 共存于同一 Worker,
# 数据沿用原 rss-robot-cf 的 namespace,零迁移)
# ---------------------------------------------------------------------------
[[kv_namespaces]]
binding = "RSS_KV"
id = "d7f86a0fb43f4450a10b786fc2635128"
# ---------------------------------------------------------------------------
# 普通变量(可以明文写在仓库里)
# SITE_DEFAULT 默认站点名(博客里 site: '优世界',必须一致)
# SITE_URL 默认站点地址,用于把相对 page_key 拼成完整 page_url
# ADMIN_NAME/EMAIL 初始管理员(首次部署后调 /api/v2/setup 初始化)
# ALLOWED_ORIGINS CORS 白名单,逗号分隔;**必须包含你博客的域名**
# ---------------------------------------------------------------------------
[vars]
SITE_DEFAULT = "优世界"
SITE_URL = "https://usj.cc"
# 站内公开 API 基址(用于把 /api/favicon 这类相对地址拼成绝对地址,友圈页在博客域名下用)
PUBLIC_API_BASE = "https://api.200181.xyz"
ADMIN_NAME = "admin"
ADMIN_EMAIL = "admin@200181.xyz"
ALLOWED_ORIGINS = "https://usj.cc,https://www.usj.cc,https://post.usj.cc,https://artalk.200181.xyz,https://api.200181.xyz,http://localhost:1313,http://127.0.0.1:1313,http://localhost:8799,http://127.0.0.1:8799"
ITEMS_PER_PAGE = "20"
PENDING_DEFAULT = "false"
# ---- RSS 订阅(rss-robot 合并进来的变量)----
# SCF_PROXY_URL 腾讯云 SCF 国内代理(scfapi.usj.cc),抓国内博客用
# FEEDS_URL 远程订阅源 JSON(回退用;KV 里已有 feeds_config,留空避免 Worker 自调用)
# FEISHU_WEBHOOK_URL 飞书机器人 webhook(可选)
SCF_PROXY_URL = "https://scfapi.usj.cc"
FEEDS_URL = ""
FEISHU_WEBHOOK_URL = ""
# 文章编辑后端(自建 editor-api 容器,Worker 只做鉴权+反代)。
# 留空 = 模块自动禁用(/api/v2/editor/* 一律 503)。令牌另走 secret,别写这里。
# writeapi.usj.cc → 国内机 119.29.215.187 的 nginx 反代 → 127.0.0.1:8017 容器
# (换机时只改这条 + 新机重跑 deploy/editor-api/bootstrap.sh,域名指向新机即可)
EDITOR_API_BASE = "https://writeapi.usj.cc"
# ⚠️ 下面两个是机密,不要写在这里,用命令写入(详见「部署清单.md」第 4 步):
# npx wrangler secret put TOKEN_SECRET
# npx wrangler secret put ADMIN_PASSWORD
# 本地开发用 .dev.vars 文件(见 .dev.vars.example)
# ---------------------------------------------------------------------------
# 邮件通知(可选)
#
# 为什么走 HTTP API 而不是 SMTP:**Cloudflare Workers 没有 TCP socket**,
# 根本连不上 SMTP 服务器。(Cloudflare 2026-04 推出的原生 Email Service
# 要 Workers Paid,本项目跑在免费版上。)
#
# 用 Resend:免费 3000 封/月(**每天上限 100 封**),本项目内置了日配额保护。
# 三个都走 secret / 环境变量:
# npx wrangler secret put RESEND_API_KEY # re_xxxxxxxx(Resend 后台创建)
# npx wrangler secret put MAIL_FROM # 形如 artalk <noreply@你的域名>
# npx wrangler secret put MAIL_ADMIN # 管理员收件邮箱;不配则不发管理员通知
#
# ⚠️ MAIL_FROM 里的域名必须先在 Resend 后台验证(加 SPF/DKIM 的 DNS 记录)。
# ⚠️ 三者任一缺失都只是「少发一类邮件」,不会影响评论提交 —— 邮件全程 try/catch。
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
# R2(可选)—— 评论里插图上传用。没建这个桶就自动禁用上传功能。
# 创建:npx wrangler r2 bucket create artalk-uploads
# ---------------------------------------------------------------------------
# [[r2_buckets]]
# binding = "UPLOADS"
# bucket_name = "artalk-uploads"
# ---------------------------------------------------------------------------
# 静态资源(必须)
# public/sidebar/ = 官方管理后台(客户端用它打开 iframe:{server}/sidebar/)
# public/dist/ = 官方客户端与插件,博客若想直接从服务端引也可以用
# 来源:Artalk v2.8.7 的 artalk_ui.tar.gz(预构建,无需前端构建环境)
# ---------------------------------------------------------------------------
[assets]
directory = "public"
binding = "ASSETS"
# ---------------------------------------------------------------------------
# 自定义域名
# 200181.xyz 的 NS 就在 Cloudflare 上,所以直接绑 artalk.200181.xyz 即可——
# custom_domain = true 会让 Cloudflare 自动建 DNS 记录 + 签 SSL 证书。
#
# 对比:usj.cc 的 NS 在 DNSPod,所以它不能这么绑(绑了会破坏又拍云/EdgeOne 调度)。
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
# 自定义域名
# 2026-10-03 起统一到 api.200181.xyz(评论 /api/v2/* + 订阅 /api/* 同一
# Worker),artalk.200181.xyz 已解绑废弃。usj.cc 的 NS 在 DNSPod 不能这样绑。
# ---------------------------------------------------------------------------
[[routes]]
pattern = "api.200181.xyz"
custom_domain = true
# ---------------------------------------------------------------------------
# 定时任务(合并 rss-robot 的抓取):
# 0 * * * * RSS 轮转抓取(每小时一批,约 3 小时覆盖全部源)
# 17 3 * * * 评论 GC(限流/验证码清理 + healthz 缓存刷新)
# 10 4 * * * 证书续期检查(探针查剩余天数,≤30 天才真正签发+部署)
# ---------------------------------------------------------------------------
[triggers]
crons = ["17 3 * * *", "0 * * * *", "10 4 * * *"]
# ---------------------------------------------------------------------------
# 资源上限 —— ★ 免费版不支持,必须注释掉,否则**部署直接被拒**
#
# 2026-10-06 实测:wrangler deploy 报
# X [ERROR] A request to the Cloudflare API (.../workers/scripts/artalk-cf/versions)
# failed. CPU limits are not supported for the Free plan. [code: 100328]
# 注意:免费版不是「忽略」这个字段,而是**整个部署失败**,
# 所以只要账号还在 Free plan,这段就必须保持注释。
#
# ★ 同时这也意味着:免费版硬顶 CPU 10ms,**证书签发功能跑不起来**
# (一次 ECDSA 签名 + 手写 DER 的 CSR 远不止 10ms)。
# 换句话说:ACME 签发/续期这条链路需要 Workers Paid($5/月)。
# 探针 / 环境自检 / 手动查询这些轻量功能在免费版完全可用。
#
# 升级到 Paid 后,把下面两行放开即可(cron 默认 30s,Paid 可到 5min):
# [limits]
# cpu_ms = 60000
# ---------------------------------------------------------------------------
[observability]
enabled = true