www_site/docs/production-deployment-2026-09-11.md

5.3 KiB
Raw Blame History

生产部署记录2026-09-11

发布

  • 发布提交:ad87a71(含 de6fdb0 邮箱/短信注册验证、c439ccb 图形验证码+唯一用户名、5b9d74a 用户资料管理与管理员删除用户、57c854a/080af11/70f64b6/be7e1f4 CMS 入口修复、ad87a71 品牌 favicon 等)。
  • 发布目录:/home/flym/releases/ad87a71www + API/home/flym/releases/cms-ad87a71CMS
  • 软链:kaotings-wwwreleases/ad87a71kaotings-cmsreleases/cms-ad87a71kaotings-apireleases/ad87a71/services/api
  • 数据库迁移:005_sms_provider.sql006_usernames.sql 已应用(schema_migrations 001006 齐全,users.username 列存在)。

本次发现并修复的问题(重要)

  1. Turbopack 外部模块缺失导致 CMS 500Next 16Turbopack生产构建会把外部依赖pino/pg/drizzle-kit/pino-pretty带内容 hash 后缀)拷贝到 .next/node_modules/<name>-<hash>/,运行时按该名字 require。
    • 本地 Windows 构建产物中 .next/node_modules/ 只有空目录(文件未写入),导致此前发布(含 09-11 上午 cms-57c854a 包)的 CMS 管理端/API 一直 500Cannot 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/080af11wwwreleases/cms-57c854aCMS已修复 .next/node_modulesnode_modules,可独立运行)。
  • 回滚:软链指回上述目录 + systemctl restart 对应服务。API 回滚需同时评估 005/006 迁移(均为新增列/表,旧代码兼容,可保留迁移)。

验收

  • systemctl is-active kaotings-api kaotings-cms kaotings-webactive ×3。
  • GET /healthz127.0.0.1:8000 与 https://www.kaotings.comok / 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 处理)。

追加CMS 管理端登录后 404 根因与修复(重要)

现象:登录 CMS 后访问 https://www.kaotings.com/cms/admin 返回 404Next 默认 "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/nextRootPageArray.isArray(params.segments) ? /${params.segments.join('/')} : null 计算 currentRoute;传入 []path 变成 "/"
  3. payload/sharedformatAdminURL{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