Files
fquiz/memory/2026-05-16.md
T
2026-05-17 00:09:33 +08:00

152 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Work Log - 发布链路切换国内镜像仓库(2026-05-16)
- 背景:
- 当前 `dev` 分支 GitHub Actions 发布阶段在远端执行 `docker login ghcr.io` / `docker compose pull` 时失败。
- 典型报错为:`Error response from daemon: Get "https://ghcr.io/v2/": EOF`
- 参考仓库 `multica-ck` 已采用“可配置国内镜像仓库 + 账号密码登录”的工作流模式。
- 本次改动:
- `/.github/workflows/main.yml`
- 将工作流默认镜像仓库从固定 `ghcr.io` 改为 `REGISTRY` / `REGISTRY_NAMESPACE` 可配置模式。
- 默认值对齐 `multica-ck``crpi-u265r07n4blchcqo.cn-shanghai.personal.cr.aliyuncs.com/ck-registry`
- 构建推送阶段改为使用 `REGISTRY_USERNAME` / `REGISTRY_PASSWORD` 登录镜像仓库。
- 部署阶段新增镜像仓库凭据校验,并将远端 `docker login ghcr.io` 改为登录 `${REGISTRY}`
- API / Web 镜像构建补充 `pull: true`,降低 runner 侧基底镜像陈旧风险。
- `/deploy/pro-deploy/.env`
- 将默认 `API_IMAGE` / `WEB_IMAGE` 从 GHCR 地址替换为阿里云个人版容器仓库地址,保证非 CI 手工部署默认也不再回落到 GHCR。
- 验证:
- `git diff --check -- .github/workflows/main.yml deploy/pro-deploy/.env` 通过,无空白/格式错误。
- 仓库内已清除工作流与生产部署默认镜像中的 `ghcr.io` 活动引用。
- 本次未直接触发 GitHub Actions 真实发布,远端连通性需在下一次 CI 执行中验证。
- 风险与关注点:
- GitHub 仓库需预先配置 `REGISTRY_USERNAME` / `REGISTRY_PASSWORD` Secrets,否则构建登录阶段会失败。
- 若未来镜像仓库或命名空间变化,只需更新仓库 Variables `REGISTRY` / `REGISTRY_NAMESPACE`,无需再改工作流逻辑。
## Work Log - 登录接口跨域拦截定位与修复(2026-05-16)
- 背景:
- 用户反馈 `http://223.109.142.84:3000/fl` 可打开,但登录时报错。
- 现场前端 bundle 实际将 API 基址写死为 `http://127.0.0.1:8000`,运行时会改写为当前主机 `223.109.142.84:8000`
- 在线 `api` 容器实际运行于另一份部署目录 `/opt/fquiz/deploy/pro-deploy`,其 `API_CORS_ORIGINS` 仅允许 `https://quiz.example.com`
- 本次改动:
- `/opt/git/fquiz/deploy/pro-deploy/.env`
-`NEXT_PUBLIC_API_BASE_URL``https://quiz.example.com/api` 修正为 `https://quiz.example.com`,避免未来重发版后前端把接口拼成 `/api/api/v1/...`
- 在线部署 `/opt/fquiz/deploy/pro-deploy/.env.prod`
-`API_CORS_ORIGINS` 调整为 `https://quiz.example.com,http://223.109.142.84:3000`
- 使用现有镜像强制重建 `api` 容器,使新的 CORS 白名单立即生效。
- 验证:
- `curl -i http://127.0.0.1:8000/health` 返回 `200 OK`
- `curl -i -X OPTIONS http://127.0.0.1:8000/api/v1/auth/login -H 'Origin: http://223.109.142.84:3000' -H 'Access-Control-Request-Method: POST'`
返回 `200 OK`,且响应头包含 `access-control-allow-origin: http://223.109.142.84:3000`
- `curl -i -X POST http://127.0.0.1:8000/api/v1/auth/login -H 'Origin: http://223.109.142.84:3000' -H 'Content-Type: application/json' --data '{"user_id":"admin","password":"wrong-password"}'`
返回 `401 Unauthorized`,同时保留 `access-control-allow-origin: http://223.109.142.84:3000`,说明跨域链路已打通,剩余仅取决于账号密码本身。
- 风险与关注点:
- 在线 `api` 仍配置 `REFRESH_COOKIE_SECURE=true`;若继续通过纯 HTTP IP 访问,刷新 token cookie 可能不会被浏览器持久化。短期内不影响本次“登录预检被拦截”的修复,但后续若要稳定保留登录态,建议切到 HTTPS 域名访问,或在明确接受风险的前提下改为 `false`
## Work Log - 认证刷新超时改为同源反代(2026-05-16)
- 背景:
- 浏览器请求 `POST http://223.109.142.84:8000/api/v1/auth/refresh` 超时,控制台报 `Failed to fetch`
- 容器内访问 `http://223.109.142.84:3000/fl` 正常返回 `200`,但访问 `http://223.109.142.84:8000/health` 仍超时;同时 `http://127.0.0.1:8000/health``api` 容器内正常返回 `200`
- 说明故障不在 `auth/refresh` 业务逻辑,而在“浏览器直连公网 `:8000`”这条访问链路。
- 本次改动:
- `web/src/lib/api.ts`
- 浏览器端在发现构建注入的 API 基址仍为 loopback 且当前页面不在 loopback 主机时,不再改写到 `当前主机:8000`,而是直接回落到 `window.location.origin`
- `deploy/pro-deploy/compose.yml`
- 生产部署新增 `proxy`nginx)服务,占用宿主机 `3000`
- `web` 改为仅在 Compose 内网暴露 `3000`,不再直接占用宿主机端口。
- `deploy/pro-deploy/nginx.conf`
- `/api/*` 反代到 `api:8000`
- `/api/v1/ws` 使用 Upgrade 头反代到 `api:8000`
- 其余页面流量反代到 `web:3000`
- 验证:
- 本地 `nft list ruleset` 显示 Docker 已为宿主机 `3000/8000` 建立映射,但容器内访问公网 `:8000` 超时、访问公网 `:3000` 正常,支持“对外入口应统一走 `3000` 反代”的判断。
- 待同步部署目录并重建 `web/proxy` 容器后,再做浏览器与 `curl` 复测。
- 风险与关注点:
- 当前在线 `REFRESH_COOKIE_SECURE=true`;若继续通过纯 HTTP IP 访问,浏览器可能仍不会持久化 refresh cookie。若部署后出现“登录后刷新即掉线”,需将当前环境的 `REFRESH_COOKIE_SECURE` 调整为 `false` 或切到 HTTPS 入口。
## Work Log - 登录入口迁移到 `/fl/login`2026-05-16
- 背景:
- 当前前端登录页挂在应用根路径;在生产 basePath=`/fl` 下,对外登录地址表现为 `/fl`
- 需求要求将登录路由显式调整为 `/fl/login`,同时保留旧入口兼容跳转。
- 本次改动:
- `web/src/app/login/page.tsx`
- 新增独立登录页,沿用现有登录表单、记住密码和登录态自动跳转逻辑。
- `web/src/app/page.tsx`
- 根页改为重定向到 `/login`,不再直接承载登录表单。
- `web/src/middleware.ts`
-`/login` 标记为公开直达路由,避免被后台 rewrite 到 `/admin/login`
- `web/src/components/auth-provider.tsx`
- 退出登录后统一跳转到 `/login`
- `web/src/app/admin/layout.tsx`
- 未登录态提示中的“前往登录”入口改为 `/login`
- `MEMORY.md`
- 同步更新长期路由口径:`/login` 为规范登录入口,`/` 仅做跳转。
- 验证:
- `npm --prefix web run lint -- src/app/page.tsx src/app/login/page.tsx src/middleware.ts src/components/auth-provider.tsx src/app/admin/layout.tsx`
通过;仅保留既有 `<img>` 使用警告,无新增 lint error。
- 已本地确认 Next.js 16 安装包的 app redirect 渲染链会按 basePath 处理重定向,当前 `redirect("/login")` 口径可用于 `/fl/login` 场景。
- `npm --prefix web run build` 已启动并进入 `next build --webpack`,但在本次会话等待窗口内未返回最终退出码;期间未出现与本次改动相关的编译报错输出。
- 风险与关注点:
- 仓库内仍有多处“返回首页”按钮保留指向 `/`;当前会经过根页跳转到 `/login`,功能不受影响,但若后续希望所有入口都直接落到规范地址,可再统一替换为 `/login`
## Work Log - 菜单旧路由兼容修复(2026-05-16)
- 背景:
- 用户反馈 `/fl/user` 按预期应进入用户页面,但实际返回 404。
- 当前前端真实页面路径为 `/users`,而部分历史菜单 path/手输地址仍可能使用旧别名(如 `/user``/role``/menu`)。
- 本次改动:
- `web/src/lib/app-route-path.ts`
- 新增统一路由规范化 helper,集中维护旧菜单别名到正式公开路由的映射。
- `web/src/middleware.ts`
-`/user``/role``/menu` 等旧地址,以及 `/admin/*` 旧入口,统一先重定向到规范公开路由,再走后台 rewrite。
- `web/src/app/admin/layout.tsx`
- 后台菜单树 path 统一先做规范化,避免菜单点击后高亮丢失或 path 仍指向旧地址。
- `web/src/app/admin/menus/page.tsx`
- 菜单管理页读取菜单列表时展示规范化 path;提交菜单编辑时也会把旧别名收敛到正式地址。
- `MEMORY.md`
- 补充“前端菜单路由兼容口径”,记录规范地址与旧别名自动收敛规则。
- 验证:
- `npm --prefix web run lint -- src/lib/app-route-path.ts src/middleware.ts src/app/admin/layout.tsx src/app/admin/menus/page.tsx`
通过;仅保留既有 `<img>` warning,无新增 lint error。
- `git diff --check -- web/src/lib/app-route-path.ts web/src/middleware.ts web/src/app/admin/layout.tsx web/src/app/admin/menus/page.tsx`
通过。
- 风险与关注点:
- 当前别名映射基于已知历史菜单路径补齐;若库里还存在其他非常规旧 path,仍需按实际反馈继续补别名表。
## Work Log - 生产入口 `/fl/login` 404 排查与 host Nginx 修复(2026-05-16
- 背景:
- 线上 `https://www.quizck.cn/fl/login` 一度返回 404,但仓库内 `web` 容器与本地代理均已包含 `/login` 页面。
- 进一步比对发现,问题出在宿主机 Nginx 的 `/fl` 精确匹配:`location = /fl { return 301 /fl/; }` 会把入口导向 `/fl/`,而 Next 在 `/fl/` 上又会归一回 `/fl`,形成不必要的重定向回环/错路由链。
- 本次修复:
- `/etc/nginx/conf.d/quiz.conf`
-`location = /fl` 的重定向目标改为 `/fl/login`
- 保留 `location ^~ /fl/` 继续反代到 `127.0.0.1:3000`
- 执行 `nginx -t && nginx -s reload` 让配置立即生效。
- 验证:
- `curl -I https://www.quizck.cn/fl/login` 返回 `200 OK`
- `curl -IL https://www.quizck.cn/fl` 返回 `301 -> /fl/login -> 200`
- `curl -IL https://www.quizck.cn/fl/` 返回 `308 -> /fl -> /fl/login -> 200`
- 风险与关注点:
- `/fl/` 仍会多一次跳转,但不再出现 404。
- 后续若统一外部入口,优先直接使用 `/fl/login`,避免再依赖 `/fl` 的归一逻辑。