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
289 lines
9.3 KiB
Markdown
289 lines
9.3 KiB
Markdown
# 部署清单(照着敲,约 10 分钟)
|
||
|
||
在 `artalk-cf` 目录里执行。**第 9 步(域名)有个必须先想清楚的坑**,其余都是机械操作。
|
||
|
||
需要你有的东西:Cloudflare 账号、Node.js(本机已有 22.x)、一个能连上 Cloudflare 的网络。
|
||
|
||
---
|
||
|
||
## 0. 先确认环境
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
npx wrangler login
|
||
```
|
||
|
||
会弹出浏览器让你授权(这一步必须你自己点,我代不了)。
|
||
成功后会显示 `Successfully logged in.`
|
||
|
||
检查:
|
||
|
||
```bash
|
||
npx wrangler whoami
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 建 D1 数据库
|
||
|
||
```bash
|
||
npx wrangler d1 create artalk-cf
|
||
```
|
||
|
||
输出里会有一行 `database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"`,**复制它**。
|
||
|
||
---
|
||
|
||
## 3. 把 database_id 填进配置
|
||
|
||
编辑 `wrangler.toml`,把这一行改掉:
|
||
|
||
```toml
|
||
[[d1_databases]]
|
||
binding = "DB"
|
||
database_name = "artalk-cf"
|
||
database_id = "00000000-0000-0000-0000-000000000000" # ← 换成刚才复制的那串
|
||
```
|
||
|
||
同一文件里再确认这几项是否符合你的情况:
|
||
|
||
```toml
|
||
[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. 写入两个机密(不要写进文件)
|
||
|
||
```bash
|
||
# 签 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. 建表
|
||
|
||
```bash
|
||
npx wrangler d1 execute artalk-cf --remote --file=./schema.sql
|
||
```
|
||
|
||
应该看到若干条 `🚣 Executed 8 commands` 之类的成功输出。
|
||
|
||
核对:
|
||
|
||
```bash
|
||
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. 部署
|
||
|
||
```bash
|
||
npx wrangler deploy
|
||
```
|
||
|
||
输出末尾会给一个地址:
|
||
|
||
```
|
||
Uploaded artalk-cf (x.xx sec)
|
||
https://artalk-cf.<你的账号子域>.workers.dev
|
||
```
|
||
|
||
**把它记下来**,下面用 `<BASE>` 代替。
|
||
|
||
---
|
||
|
||
## 7. 导入评论数据(**必须在初始化管理员之前**)
|
||
|
||
```bash
|
||
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. 初始化站点与管理员
|
||
|
||
```bash
|
||
curl -X POST <BASE>/api/v2/setup
|
||
```
|
||
|
||
期望返回:
|
||
|
||
```json
|
||
{"msg":"Success","site":"优世界","admins":["admin@200181.xyz"],"reseted":false}
|
||
```
|
||
|
||
它会建默认站点、把 `ADMIN_NAME/EMAIL/PASSWORD` 写成管理员(密码存 PBKDF2 哈希)。
|
||
|
||
**立刻验证管理员能登录**(账号名或邮箱都行):
|
||
|
||
```bash
|
||
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`,取消注释并改成你的域名:
|
||
```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`:
|
||
|
||
```toml
|
||
[params.artalk]
|
||
server = "https://artalk-cf.你的域名" # ← 只改这一行
|
||
site = "优世界"
|
||
```
|
||
|
||
然后按你平时的流程发布(写作后台点发布,或按 `hugo-writeserver-publish-ops` 里那套精确发布命令)。
|
||
|
||
**前端一个字符都不用动**——客户端调的就是 `${server}/api/v2/...`,
|
||
`pageKey` 用 `.RelPermalink`(`/20210911.html`),和 D1 里的 `page_key` 完全对应。
|
||
|
||
---
|
||
|
||
## 11. 验收
|
||
|
||
```bash
|
||
bash tools/smoke.sh https://artalk-cf.你的域名
|
||
```
|
||
|
||
然后拿 token 再跑一遍后台用例:
|
||
|
||
```bash
|
||
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 |
|
||
|
||
实时日志:
|
||
|
||
```bash
|
||
npx wrangler tail
|
||
```
|
||
|
||
---
|
||
|
||
## 附:也可以让我代跑
|
||
|
||
如果你不想自己敲,可以给我一个 **Cloudflare API Token**(权限只需
|
||
`Workers Scripts: Edit` + `D1: Edit` + `Account Settings: Read`),我可以直接执行第 2~8 步。
|
||
用完请立刻在 Cloudflare 后台把那个 token 删掉。
|
||
|
||
第 1 步(浏览器登录授权)和第 9 步(改 NS)无论如何都得你自己来。
|