From e2657eecb8f296d93c53c60798b034496f2c2f7d Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 13 Jul 2026 17:36:46 +0200 Subject: [PATCH] docs: add UniDesk Nginx operations skill --- .agents/skills/unidesk-nginx/SKILL.md | 70 +++++++++++++++++++ .../skills/unidesk-nginx/agents/openai.yaml | 4 ++ .../unidesk-nginx/references/operations.md | 53 ++++++++++++++ .../references/troubleshooting.md | 46 ++++++++++++ AGENTS.md | 1 + docs/reference/pk01.md | 6 +- docs/reference/platform-infra.md | 11 +-- 7 files changed, 178 insertions(+), 13 deletions(-) create mode 100644 .agents/skills/unidesk-nginx/SKILL.md create mode 100644 .agents/skills/unidesk-nginx/agents/openai.yaml create mode 100644 .agents/skills/unidesk-nginx/references/operations.md create mode 100644 .agents/skills/unidesk-nginx/references/troubleshooting.md diff --git a/.agents/skills/unidesk-nginx/SKILL.md b/.agents/skills/unidesk-nginx/SKILL.md new file mode 100644 index 00000000..437fe0df --- /dev/null +++ b/.agents/skills/unidesk-nginx/SKILL.md @@ -0,0 +1,70 @@ +--- +name: unidesk-nginx +description: >- + UniDesk Nginx 负载均衡与请求日志服务运维技能。用户提到 Nginx、platform-infra nginx、 + nginx-lb-logger、PK01 Nginx、HTTP 负载均衡、NGINX_ROUTES、多负载端口、JSONL 请求日志、 + logger API、日志查询下载清理或 LOGGER_API_KEY 时使用。 +--- + +# UniDesk Nginx + +通过 `platform-infra nginx` 运维 owning YAML 选择的 Nginx host-Docker target。 +所有正式变更走受控 CLI,不直接修改 PK01 Compose、容器、systemd 或日志文件。 + +## 权威入口 + +- 配置真相:`config/platform-infra/nginx.yaml`。 +- 受控实现:`scripts/src/platform-infra-nginx.ts`。 +- 通用镜像 Demo:`/root/demo/nginx-lb-logger`。 +- 开发边界:`docs/reference/platform-infra.md`。 +- PK01 边界:`docs/reference/pk01.md`。 + +涉及 YAML 职责拆分时同时加载 `$unidesk-ymalops`。 +涉及跨 host 现场修改或验证时同时加载 `$dad-dev` 与 `$unidesk-trans`。 + +## 高频入口 + +```bash +bun scripts/cli.ts platform-infra nginx plan --target PK01 +bun scripts/cli.ts platform-infra nginx apply --target PK01 --dry-run +bun scripts/cli.ts platform-infra nginx apply --target PK01 --confirm +bun scripts/cli.ts platform-infra nginx status --target PK01 +``` + +`apply --confirm` 默认返回异步 job。 +只用返回的 `job status` 命令短轮询,禁止改成长 SSH 连接等待完整传输和验证。 + +## 操作顺序 + +1. 读取 owning YAML,确认 target、routes、资源、镜像产物和 Secret `sourceRef`。 +2. 运行 `plan`,要求镜像、Compose 插件和 Secret 摘要均有效。 +3. 配置变更先运行 `apply --dry-run`,确认 mutation 为 false。 +4. 用户要求部署时运行 `apply --confirm`,跟踪返回的异步 job 到终态。 +5. 运行正式 `status`,要求镜像 ID、健康接口、日志状态和测试后端清理均通过。 + +完整操作与配置变更见 [references/operations.md](references/operations.md)。 +失败分层和已确认陷阱见 [references/troubleshooting.md](references/troubleshooting.md)。 + +## 不可越过的边界 + +- 通用镜像只在 NC01 构建;Master server 和 PK01 不执行镜像构建。 +- PK01 正式部署只走 `platform-infra nginx apply`,不使用 Demo Compose 代替。 +- target、监听端口、上游、资源、日志上限和 API key 来源只写 owning YAML。 +- Nginx 配置使用 `NGINX_*`,日志收集和管理配置使用 `LOGGER_*`。 +- API key 只披露 sourceRef、key 名、presence 和 fingerprint,禁止打印明文。 +- 除健康接口外,logger API 必须传入 `X-API-Key`。 +- JSONL 只能由 Nginx `access_log` 写入;验证器不得生成或补写日志。 +- PK01 验证只发送四个串行请求,不执行压力测试。 +- 验证后端必须是临时 host Python/systemd 服务,不能放进容器。 +- 验证退出后必须删除后端脚本和 unit,只保留 Nginx 容器。 +- 本机临时 HTTP 制品源由 CLI 创建和撤销,不得作为常驻下载服务。 + +## 关闭标准 + +- `backendSequence` 与 `loggedSequence` 都是 + `backend-1,backend-2,backend-1,backend-2`。 +- 未认证 logger API 返回 `401`。 +- info、tail、download 和 clear 均成功。 +- `status.summary.ok=true`、健康状态为 `200`、镜像 ID 匹配。 +- `activeTestBackends=0`,测试脚本和 systemd unit 不存在。 +- 本机临时 HTTP 目录和进程已经撤销。 diff --git a/.agents/skills/unidesk-nginx/agents/openai.yaml b/.agents/skills/unidesk-nginx/agents/openai.yaml new file mode 100644 index 00000000..b3d19553 --- /dev/null +++ b/.agents/skills/unidesk-nginx/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "UniDesk Nginx" + short_description: "受控部署、验证和运维 UniDesk Nginx 负载均衡与日志服务" + default_prompt: "使用 $unidesk-nginx 按 owning YAML 安全部署并验证 UniDesk Nginx 服务。" diff --git a/.agents/skills/unidesk-nginx/references/operations.md b/.agents/skills/unidesk-nginx/references/operations.md new file mode 100644 index 00000000..d28fa31a --- /dev/null +++ b/.agents/skills/unidesk-nginx/references/operations.md @@ -0,0 +1,53 @@ +# 受控操作 + +## 配置路由 + +- 只在 `config/platform-infra/nginx.yaml` 修改运行事实。 +- `targets..runtime.routes` 支持一个或多个监听端口。 +- 每个监听端口支持一个或多个 `host`、`port` 上游。 +- CLI 把 routes 数组渲染为 `NGINX_ROUTES`,源码不保存应用专用端口。 +- 一个上游是合法配置,不需要保留虚假的第二个上游。 + +## 配置 Logger + +- `LOGGER_PATH` 指向容器内 JSONL 文件。 +- `LOGGER_MAX_BYTES` 和检查周期必须明确设置,避免无限增长。 +- `LOGGER_ADMIN_PREFIX` 控制 logger API 前缀。 +- `apiKey.sourceRef`、`sourceKey` 和 `targetKey` 是唯一 Secret 来源。 +- 健康接口不鉴权;查询、tail、下载和清理均使用 `X-API-Key`。 + +## 镜像与制品 + +- 镜像源码和本地验证入口位于 `/root/demo/nginx-lb-logger`。 +- 镜像在 NC01 构建并验证单端口、多端口、原始请求恢复、API 和自动清理。 +- owning YAML 固定镜像标签、镜像 ID、产物字节数和 SHA-256。 +- PK01 使用 YAML 固定的官方静态 Compose 二进制,不能复用 Master 发行版动态插件。 +- CLI 通过本机短时 HTTP server 暴露已校验制品。 +- Compose 插件先快速 gzip,PK01 解压后校验原始 SHA-256。 +- 无论 apply 成功或失败,都撤销本机 HTTP server 和临时目录。 + +## 部署与验收 + +```bash +bun scripts/cli.ts platform-infra nginx plan --target PK01 +bun scripts/cli.ts platform-infra nginx apply --target PK01 --dry-run +bun scripts/cli.ts platform-infra nginx apply --target PK01 --confirm +``` + +- 从 confirmed apply 输出取得 `statusCommand`。 +- 轮询 job 到 `succeeded` 或 `failed`,不要重复提交并行 apply。 +- 成功后运行: + +```bash +bun scripts/cli.ts platform-infra nginx status --target PK01 +``` + +- status 必须确认: + - 容器正在运行; + - 当前镜像 ID 等于 YAML 期望值; + - logger 健康接口返回 `200`; + - `activeTestBackends` 为 `0`; + - 输出不包含 API key 明文。 + +验证后端撤除后,测试业务端口没有活动上游属于预期状态。 +部署真实应用前先把 routes 改为真实 host 服务,再走同一受控 apply。 diff --git a/.agents/skills/unidesk-nginx/references/troubleshooting.md b/.agents/skills/unidesk-nginx/references/troubleshooting.md new file mode 100644 index 00000000..f2630b5a --- /dev/null +++ b/.agents/skills/unidesk-nginx/references/troubleshooting.md @@ -0,0 +1,46 @@ +# 排障 + +## 先看受控状态 + +```bash +bun scripts/cli.ts platform-infra nginx plan --target PK01 +bun scripts/cli.ts platform-infra nginx status --target PK01 +``` + +只在受控输出不足时使用 `trans PK01` 做有界只读诊断。 +诊断不能替代最后一次正式 `status`。 + +## Compose 不可用 + +- 症状:`docker compose` 不存在或插件 metadata 无效。 +- 先直接运行 YAML 固定的 Compose 二进制 `version`,再检查 `docker info` 插件警告。 +- Master 的发行版插件可能依赖较新的 GLIBC,不能直接复制到 Ubuntu 20.04 的 PK01。 +- 使用 owning YAML 固定的官方静态二进制及 SHA-256,不在 PK01 现场下载漂移版本。 + +## 制品传输超时 + +- 症状:`trans upload` 大文件长期无进度,或单次 SSH 到 60 秒后退出 `124`。 +- 正常路径应为本机临时 HTTP 源、PK01 远端 job 和短轮询。 +- 不要把大镜像改回 base64 分块上传,也不要用长 SSH 等待下载、Docker load 和验证。 +- apply 结束后检查 `/tmp/unidesk-nginx-artifacts` 不存在,临时 HTTP 端口已释放。 + +## Logger API 拒绝 + +- `401` 表示没有 `X-API-Key`,属于正常鉴权结果。 +- `403` 表示 key 不匹配。 +- 只核对 Secret sourceRef、key 名、presence 和 fingerprint。 +- 禁止读取远端环境文件并打印明文,也禁止把 key 放进 job 命令参数。 + +## 业务端口无响应 + +- 先看 YAML routes 是否仍指向已撤除的测试端口。 +- 验收成功后删除两个测试后端是设计要求,不代表 Nginx 容器异常。 +- 部署真实应用时只修改 YAML routes,不改镜像源码。 +- 多端口问题按每个 `listenPort` 独立核对上游,不推断所有端口共享同一组后端。 + +## 测试后端残留 + +- 正式 status 的 `activeTestBackends` 必须为 `0`。 +- 检查两个 unit、Python 脚本和 enable symlink 是否仍存在。 +- 若 apply 失败在验证阶段,优先修复 CLI 的退出清理路径,再重跑受控 apply。 +- 不把临时后端长期保留为运行依赖。 diff --git a/AGENTS.md b/AGENTS.md index 8654185f..c1f31528 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -102,6 +102,7 @@ - 优先走 `$unidesk-trans` 的 `trans apply-patch`; - route/cwd 见 `docs/reference/cli.md`。 - P0: 专项技能路由: + - Nginx 负载均衡、logger API 和 PK01 host-Docker 运维走 `$unidesk-nginx`; - Web/Workbench/Playwright/web-probe 走 `$unidesk-webdev`; - OTel/Tempo/trace 走 `$unidesk-otel`; - Web 哨兵和周期巡检走 `$unidesk-monitor`。 diff --git a/docs/reference/pk01.md b/docs/reference/pk01.md index c11fefb4..556262f5 100644 --- a/docs/reference/pk01.md +++ b/docs/reference/pk01.md @@ -195,14 +195,10 @@ Interpretation guide: ## Nginx Host-Docker 受控部署 - PK01 的 Nginx 负载均衡器由 `config/platform-infra/nginx.yaml` 管理。 +- 日常部署、状态、logger API 和排障统一见 `$unidesk-nginx`。 - 部署形态与 PK01 Sub2API 一致,使用 UniDesk YAML-first 的 host-Docker Compose 入口。 -- 正式命令是 `bun scripts/cli.ts platform-infra nginx apply --target PK01 --confirm`。 - apply 默认提交异步 job;长传输、镜像加载和验证不能占用单次 SSH 长连接。 - 容器使用 host network,并限制为 `64m` 内存、`0.25` CPU 和 64 个 PID。 - 业务监听端口、上游列表、管理端口、日志上限和 logger API key 来源均来自 owning YAML。 - PK01 不构建镜像;镜像在 NC01 构建后以 SHA-256 和镜像 ID 校验的产物下发。 -- 验证期间临时创建两个 loopback host Python/systemd 后端。 -- 验证固定发送四个串行请求,并核对响应后端与 Nginx JSONL 记录顺序。 -- 验证 logger API 的未认证拒绝、查询、tail、下载和清理能力。 -- 验证结束后删除两个后端及其 unit,保留 Nginx 容器和已清空的日志文件。 - `platform-infra nginx status --target PK01` 必须报告测试后端活动数为零。 diff --git a/docs/reference/platform-infra.md b/docs/reference/platform-infra.md index 04fc59cc..ac3f2d2d 100644 --- a/docs/reference/platform-infra.md +++ b/docs/reference/platform-infra.md @@ -327,17 +327,12 @@ This policy must be included in the `sub2api plan` / `apply` manifest rendering ## Nginx 负载均衡与 Logger 边界 - Nginx host-Docker 服务的配置真相是 `config/platform-infra/nginx.yaml`。 -- 正式入口是 `platform-infra nginx plan|apply|status`,不得用 Demo 脚本直接修改 PK01。 +- 日常命令、部署、验收和排障统一见 `$unidesk-nginx`。 +- 正式入口是 `platform-infra nginx plan|apply|status`。 +- 不得用 Demo 脚本直接修改 PK01。 - 镜像由 owning YAML 固定产物路径、SHA-256 和镜像 ID,并在 NC01 构建。 - `targets..runtime.routes` 是业务监听端口与上游的唯一真相。 -- 一个 target 可以声明一个或多个监听端口,每个端口可以声明一个或多个 HTTP 上游。 - CLI 将路由数组渲染为容器的 `NGINX_ROUTES`,不在源码中保存应用专用端口。 -- Nginx 配置使用 `NGINX_*`,日志收集和管理配置使用 `LOGGER_*`。 - logger API key 只允许由 YAML `sourceRef`、`sourceKey` 和 `targetKey` 下发。 - API key 输出只披露 presence 与 fingerprint,禁止输出或嵌入受控 job 命令。 -- 除健康检查外,logger 查询、tail、下载和清理接口均要求 `X-API-Key`。 - JSONL 文件由 Nginx `access_log` 写入,验证器不得生成或补写日志。 -- `LOGGER_MAX_BYTES` 与检查周期必须由 YAML 明确设置,避免日志无限增长。 -- PK01 验证只发送四个串行请求,不执行压力测试。 -- 两个验证后端必须是 PK01 host Python/systemd 服务,不能作为容器部署。 -- 验证退出时必须停止并删除后端脚本和 unit;正式 Nginx 容器继续运行。