Files
blog/blog-admin/部署清单.md
T

288 lines
9.3 KiB
Markdown
Raw Normal View History

# 部署清单(照着敲,约 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)无论如何都得你自己来。