Files
blog/blog-admin/部署清单.md
T
zqlit a74b3c7127
Deploy to Production / pre-check (push) Successful in 58s
Deploy to Production / build (push) Successful in 4m3s
Deploy to Production / deploy-edgeone (push) Successful in 3m48s
Deploy to Production / finalize (push) Successful in 26s
Deploy to Production / notify-failure (push) Skipped
归档 artalk-cf 评论后端 + rss-robot 到 blog-admin(含技术选型/模块分布 README)
2026-10-04 08:45:40 +08:00

9.3 KiB
Raw Blame History

部署清单(照着敲,约 10 分钟)

在 artalk-cf 目录里执行。第 9 步(域名)有个必须先想清楚的坑,其余都是机械操作。

需要你有的东西:Cloudflare 账号、Node.js(本机已有 22.x)、一个能连上 Cloudflare 的网络。


0. 先确认环境

cd artalk-cf
npm install
node node_modules/typescript/bin/tsc --noEmit        # 应该没有任何输出

这台机器上 npm 可能被沙箱网络打断(stub 装不全)。若报 Cannot find module, 重跑 npm install 直到 node_modules/wrangler/package.json 能读出版本号。


1. 登录 Cloudflare

npx wrangler login

会弹出浏览器让你授权(这一步必须你自己点,我代不了)。 成功后会显示 Successfully logged in.

检查:

npx wrangler whoami

2. 建 D1 数据库

npx wrangler d1 create artalk-cf

输出里会有一行 database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",复制它。


3. 把 database_id 填进配置

编辑 wrangler.toml,把这一行改掉:

[[d1_databases]]
binding = "DB"
database_name = "artalk-cf"
database_id = "00000000-0000-0000-0000-000000000000"   # ← 换成刚才复制的那串

同一文件里再确认这几项是否符合你的情况:

[vars]
SITE_DEFAULT = "优世界"                       # 必须和博客 hugo.toml 里的 site 一致
SITE_URL = "https://usj.cc"
ADMIN_NAME = "小赵"
ADMIN_EMAIL = "z@usj.cc"
ALLOWED_ORIGINS = "https://usj.cc,https://www.usj.cc,https://post.usj.cc,http://localhost:1313"

ALLOWED_ORIGINS 少了博客域名的话,浏览器会因 CORS 拒绝评论请求(评论区一直转圈)。


4. 写入两个机密(不要写进文件)

# 签 token 的密钥:先生成一串随机的
node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))"

npx wrangler secret put TOKEN_SECRET     # 粘贴上面那串
npx wrangler secret put ADMIN_PASSWORD   # 输入你要用的后台密码

(本地开发时改用 .dev.vars:cp .dev.vars.example .dev.vars 然后改值。)


5. 建表

npx wrangler d1 execute artalk-cf --remote --file=./schema.sql

应该看到若干条 🚣 Executed 8 commands 之类的成功输出。

核对:

npx wrangler d1 execute artalk-cf --remote --command \
  "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;"

应含:captcha_challenges captcha_passes comments notifies pages rate_limits settings sites users votes


6. 部署

npx wrangler deploy

输出末尾会给一个地址:

Uploaded artalk-cf (x.xx sec)
  https://artalk-cf.<你的账号子域>.workers.dev

把它记下来,下面用 <BASE> 代替。


7. 导入评论数据(必须在初始化管理员之前)

python tools/import_artrans.py        # 默认只导「优世界」,跳过朋友那三个站
bash tools/import-out/run.sh --remote

脚本会打印:

源文件 4048 条,按站点筛选后 3440 条 -> 归入站点「优世界」
用户 491 个
页面 91 个
评论 3339 条(其中回复 1791 条)
跳过 101 条:page_key 为空 101、昵称或邮箱为空 0、id 非法 0

最后 run.sh 会跑一段自检,打印各表条数,对一下: sites 1 / pages 91 / users 491 / comments 3339 / replies 1791

⚠️ 两个坑

  1. 00-reset-and-site.sql 会清空 comments/pages/users/sites 四张表—— 所以它会把第 8 步建的管理员一起删掉。顺序必须是「先导入、后初始化」。 库里已有数据时也别再跑,会被清空。
  2. wrangler d1 execute --remote 会先问一次确认,脚本里已经带了 -y。 如果你是手动逐条敲命令,漏了 -y 会直接报错退出。

8. 初始化站点与管理员

curl -X POST <BASE>/api/v2/setup

期望返回:

{"msg":"Success","site":"优世界","admins":["admin@200181.xyz"],"reseted":false}

它会建默认站点、把 ADMIN_NAME/EMAIL/PASSWORD 写成管理员(密码存 PBKDF2 哈希)。

立刻验证管理员能登录(账号名或邮箱都行):

curl -X POST <BASE>/api/v2/user/access_token \
  -H 'Content-Type: application/json' \
  -d '{"email":"admin","password":"你刚设的密码"}'

返回里有 "token":"..." 就对了。没有 token 说明第 4 步的密码没写进去。

忘了密码想重设:curl -X POST "<BASE>/api/v2/setup?force=<TOKEN_SECRET>", TOKEN_SECRET 就是你第 4 步写进去的那串(拿它当"部署密钥"用)。


9. ★ 域名:这一步有个坑,先想清楚

问题

Cloudflare Worker 的自定义域名要求「域名的 NS 托管在 Cloudflare」。 官方文档写得很明确:绑定自定义域名时,Cloudflare 会自动创建 DNS 记录和 SSL 证书—— 这需要 zone 在 Cloudflare 里。外部 DNS 用 CNAME 直接指过去,社区反馈是"各种奇奇怪怪的错误"。

而 usj.cc 的 NS 在 DNSPod(还挂着又拍云 + 腾讯云 EdgeOne 的调度)。 千万不要为了评论 API 把整站 NS 搬去 Cloudflare——那会把现有的国内双 CDN 链路一起弄坏。

四个选项

选项 做法 代价 建议
A. 另用一个 CF 托管域名 用另一个域名(新注册的也行,便宜)把 NS 放到 Cloudflare,绑 artalk-cf.<那个域名> 一年域名钱 ✅ 推荐
B. 先用 workers.dev 第 6 步的地址直接当正式地址 大陆访问不通,只能自测 仅用于验证功能
C. DNSPod 加 CNAME artalk-cf CNAME 到 <worker>.workers.dev 官方不支持,可能不通/证书异常 可以试,别当正式方案
D. 整站 NS 迁到 Cloudflare usj.cc → Cloudflare 会破坏又拍云/EdgeOne 调度 ❌ 不要

选了 A 之后怎么做

  1. 新域名加进 Cloudflare → 按提示把 NS 改到 Cloudflare
  2. 打开 wrangler.toml,取消注释并改成你的域名:
    [[routes]]
    pattern = "artalk-cf.你的域名"
    custom_domain = true
    
  3. npx wrangler deploy
  4. 把域名加进 ALLOWED_ORIGINS 后再 deploy 一次
  5. curl https://artalk-cf.你的域名/api/v2/healthz 应返回 {"ok":true,...}

10. 接到博客上(改一行 + 重新发布)

编辑 E:\GitHub\blog\hugo.toml:

[params.artalk]
  server = "https://artalk-cf.你的域名"    # ← 只改这一行
  site = "优世界"

然后按你平时的流程发布(写作后台点发布,或按 hugo-writeserver-publish-ops 里那套精确发布命令)。

前端一个字符都不用动——客户端调的就是 ${server}/api/v2/..., pageKey 用 .RelPermalink(/20210911.html),和 D1 里的 page_key 完全对应。


11. 验收

bash tools/smoke.sh https://artalk-cf.你的域名

然后拿 token 再跑一遍后台用例:

TOKEN=$(curl -s -X POST https://artalk-cf.你的域名/api/v2/user/access_token \
  -H 'Content-Type: application/json' \
  -d '{"email":"z@usj.cc","password":"你的密码"}' | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log(JSON.parse(s).token))")
TOKEN=$TOKEN bash tools/smoke.sh https://artalk-cf.你的域名

手动验收清单

  • 打开 https://artalk-cf.你的域名/sidebar/ —— 能看到 Artalk 后台登录页
  • 用邮箱 + 密码登录进去,能看到 3339 条评论
  • 打开博客任意一篇有评论的文章 —— 评论、回复层级、博主徽章都对
  • 打开 /comment.html(994 条那篇)—— 分页/加载更多正常
  • 发一条新评论 —— 立刻出现
  • 后台改一条评论的置顶/审核状态 —— 前台刷新后生效

12. 出问题怎么查

现象 原因 处理
评论区一直转圈 CORS:ALLOWED_ORIGINS 没有博客域名 加上域名重新 deploy
401 Unauthorized 登录失败 第 4 步密码没写进去 npx wrangler secret put ADMIN_PASSWORD 后重新跑第 7 步
后台打不开、404 /sidebar/ 静态资源没上传 确认 artalk-cf/public/sidebar/index.html 存在,重新 deploy
评论为空但后台有数据 page_key 对不上 检查博客的 pageKey 是不是 /xxx.html;D1 里 SELECT page_key FROM comments LIMIT 5 比对
部分回复层级错乱 导入时 rid 没回填 确认 run.sh 里 04-rid-fix-*.sql 都执行过了
报 Too many requests 限流生效(同 IP 60 秒 5 条) 正常行为;管理员发表不受限
前端弹版本不匹配黄条 客户端版本 ≠ 服务端上报版本 服务端固定报 2.8.7;若你把博客的 Artalk.js 升级了,改 src/routes/public.ts 的 SERVER_API_VERSION
大页面(994 条评论)超时 Workers 免费版 CPU 10ms 调小客户端 pagination.pageSize,或上 Workers Paid

实时日志:

npx wrangler tail

附:也可以让我代跑

如果你不想自己敲,可以给我一个 Cloudflare API Token(权限只需 Workers Scripts: Edit + D1: Edit + Account Settings: Read),我可以直接执行第 2~8 步。 用完请立刻在 Cloudflare 后台把那个 token 删掉。

第 1 步(浏览器登录授权)和第 9 步(改 NS)无论如何都得你自己来。