2026-09-11 14:06:39 +00:00
|
|
|
|
# 生产部署记录(2026-09-11)
|
|
|
|
|
|
|
|
|
|
|
|
## 发布
|
|
|
|
|
|
|
|
|
|
|
|
- 发布提交:`ad87a71`(含 `de6fdb0` 邮箱/短信注册验证、`c439ccb` 图形验证码+唯一用户名、`5b9d74a` 用户资料管理与管理员删除用户、`57c854a`/`080af11`/`70f64b6`/`be7e1f4` CMS 入口修复、`ad87a71` 品牌 favicon 等)。
|
|
|
|
|
|
- 发布目录:`/home/flym/releases/ad87a71`(www + API)、`/home/flym/releases/cms-ad87a71`(CMS)。
|
|
|
|
|
|
- 软链:`kaotings-www`→`releases/ad87a71`、`kaotings-cms`→`releases/cms-ad87a71`、`kaotings-api`→`releases/ad87a71/services/api`。
|
|
|
|
|
|
- 数据库迁移:`005_sms_provider.sql`、`006_usernames.sql` 已应用(`schema_migrations` 001–006 齐全,`users.username` 列存在)。
|
|
|
|
|
|
|
|
|
|
|
|
## 本次发现并修复的问题(重要)
|
|
|
|
|
|
|
|
|
|
|
|
1. **Turbopack 外部模块缺失导致 CMS 500**:Next 16(Turbopack)生产构建会把外部依赖(pino/pg/drizzle-kit/pino-pretty,带内容 hash 后缀)拷贝到 `.next/node_modules/<name>-<hash>/`,运行时按该名字 require。
|
|
|
|
|
|
- 本地 Windows 构建产物中 `.next/node_modules/` 只有空目录(文件未写入),导致此前发布(含 09-11 上午 `cms-57c854a` 包)的 CMS 管理端/API 一直 500(`Cannot find module 'pino-<hash>'`),www 首页因调用 CMS API 连带 500。
|
|
|
|
|
|
- 修复:以 `releases/df6a0e4/apps/cms/.next/node_modules`(同版本依赖、hash 一致)覆盖 `cms-ad87a71/.next/node_modules` 后 CMS 恢复正常。
|
|
|
|
|
|
- 教训:**本地(Windows)构建的 CMS `.next` 不可直接用于生产**;后续 CMS 应在服务器上构建,或发布前校验 `.next/node_modules` 文件完整性(pino 包应 ≥200 文件)。
|
|
|
|
|
|
2. **服务器资源**:内存 1.9G 无 swap,服务器上跑 CMS 构建会 OOM(本次已加 4G `/swapfile`)。
|
|
|
|
|
|
3. **sudo 构建残留 root 属主文件**:曾以 sudo 在发布目录内跑 `npm run build`,产生 root 属主的 `.next` 文件,导致后续以 flym 提取覆盖失败;已清理。发布目录内构建/清理应统一属主。
|
|
|
|
|
|
4. **SSH 未认证连接限流**:该服务器 sshd 未认证并发限制很严(疑似外部扫描占用 MaxStartups),部署期间需控制连接频率、合并操作。
|
|
|
|
|
|
|
|
|
|
|
|
## 回滚
|
|
|
|
|
|
|
|
|
|
|
|
- 上一可用发布保留:`releases/080af11`(www)、`releases/cms-57c854a`(CMS,已修复 `.next/node_modules` 与 `node_modules`,可独立运行)。
|
|
|
|
|
|
- 回滚:软链指回上述目录 + `systemctl restart` 对应服务。API 回滚需同时评估 `005/006` 迁移(均为新增列/表,旧代码兼容,可保留迁移)。
|
|
|
|
|
|
|
|
|
|
|
|
## 验收
|
|
|
|
|
|
|
|
|
|
|
|
- `systemctl is-active kaotings-api kaotings-cms kaotings-web`:active ×3。
|
|
|
|
|
|
- `GET /healthz`(127.0.0.1:8000 与 https://www.kaotings.com):ok / 200。
|
|
|
|
|
|
- www:`/`、`/register`、`/login`、`/icon.png` 均 200(新代码标记 favicon 生效)。
|
|
|
|
|
|
- CMS:`/cms/admin` 200;`/cms/api/products?where[status][equals]=published` 200。
|
|
|
|
|
|
- API 门禁:`/api/v1/auth/me` 未登录 401。
|
|
|
|
|
|
|
|
|
|
|
|
## 备注
|
|
|
|
|
|
|
|
|
|
|
|
- 生产 `api.env` 尚未注入 SMTP/阿里云短信凭据(新配置项默认空值=功能关闭),注册验证能力待凭据注入后启用,属待办而非本次部署内容。
|
|
|
|
|
|
- Caddy 未改动(CMS 根路径跳转由 CMS 自身 `/cms → /cms/admin` 处理)。
|
2026-09-11 17:37:16 +00:00
|
|
|
|
|
|
|
|
|
|
## 追加:CMS 管理端登录后 404 根因与修复(重要)
|
|
|
|
|
|
|
|
|
|
|
|
**现象**:登录 CMS 后访问 `https://www.kaotings.com/cms/admin` 返回 404(Next 默认 "This page could not be found."),未登录时正常显示登录页;其它管理路径(`/account`、`/collections/*`、`/globals/*`)全部正常。与网络、DNS、浏览器、HTTP/3、CDN 无关(曾误判,已逐一排除:证书指纹一致、请求确实到达服务器并记录在 Caddy 日志中)。
|
|
|
|
|
|
|
|
|
|
|
|
**根因**(三处代码叠加):
|
|
|
|
|
|
1. `apps/cms/src/app/(payload)/admin/[[...segments]]/page.tsx` 把路由参数兜底成空数组:`segments: resolvedParams.segments ?? []`。
|
|
|
|
|
|
2. `@payloadcms/next` 的 `RootPage` 用 `Array.isArray(params.segments) ? `/${params.segments.join('/')}` : null` 计算 `currentRoute`;传入 `[]` 时 `path` 变成 `"/"`。
|
|
|
|
|
|
3. `payload/shared` 的 `formatAdminURL` 对 `{adminRoute:'/admin', path:'/'}` 返回 `"/admin/"`(带尾斜杠,且该分支不做去尾斜杠处理),于是 `currentRoute("/admin/") !== adminRoute("/admin")`。
|
|
|
|
|
|
|
|
|
|
|
|
而 `getRouteData` 中**只有根路由**的视图解析依赖 `currentRoute === adminRoute` 判断(`case 0`),条件不成立时 `DefaultView` 为空,`RootPage` 对**已登录用户**执行 `notFound()` → 404;未登录用户走另一分支,因此表现为"登录后才 404"。
|
|
|
|
|
|
|
|
|
|
|
|
**修复**:`page.tsx` 中不再把 `segments` 兜底为空数组,保持 `undefined`(`@payloadcms/next` 类型声明把 `segments` 写成必填数组,与实现不符,故加一处类型断言并注释说明)。修复后已登录访问根路由返回 200 并正常渲染 `Dashboard - Payload`。
|
|
|
|
|
|
|
|
|
|
|
|
**其它同批处理**:
|
|
|
|
|
|
- CMS 改为在服务器上构建(本地 Windows 构建产物中 `.next/node_modules/*` 符号链接会退化为空目录,不可直接部署;服务器构建会生成有效的 `-> ../../node_modules/<pkg>` 符号链接)。
|
|
|
|
|
|
- 新增 4G swap,避免服务器构建 OOM。
|
|
|
|
|
|
- Caddy 增加了访问日志(`log { output stdout }`),便于后续排查。
|
|
|
|
|
|
- 发布:`releases/cms-ad87a71-c`(含本次修复),回滚可指向 `releases/cms-ad87a71-b`(可运行,但根路由登录后 404)。
|