--- name: dokploy-gitea-deploy description: > 企业 Dockerfile 项目部署(唯一默认路径:company-deploy-mcp)。 飞书登录拿 buxi_ Key → 配置 MCP → whoami 联通 → ensure_repository + pushUrl 推代码 → create/apply plan → 轮询 → 交付 HTTPS 链接。用户永不进 Dokploy/Gitea。 触发:部署、上线、重部署、redeploy、查项目、配额、buxi_、company-deploy、企业部署。 禁止引导用户打开 Dokploy 面板或索要 DOKPLOY_API_KEY。Use when /dokploy-gitea-deploy。 metadata: short-description: "企业部署:MCP 全流程(用户不进 Dokploy)" --- # 企业部署 Skill(company-deploy-mcp) ## 0. 一句话 **用户只做两件事:① 连接中心飞书登录拿 `buxi_` Key 配到 Agent;② 说「部署」。** 其余(建库、推代码凭据、挂卷、数据库、域名、HTTPS、构建)全部由 **Agent + MCP** 完成。 | 正确 | 错误(禁止) | |------|----------------| | 调 MCP 工具部署 | 让用户打开 Dokploy 管理面板 | | 401 → 引导连接中心重拿 Key | 说「权限配置无法通过,去找管理员要 Dokploy 权限」 | | 交付 `https://buxi….loncode.site` | 索要 `DOKPLOY_API_KEY` / Gitea Token / 面板账号 | | 环境变量靠 plan(`databases[]` 等)或代码默认 | 让用户去 Dokploy 改某个应用的 env | **连接中心** `https://company-deploy-mcp.loncode.site/` = 飞书身份 + MCP 授权,**不是** Dokploy 面板。 **Dokploy** 只被控制面服务端调用,**业务用户与业务 Agent 默认不可见、不需要、不引导**。 --- ## 1. 安装本 Skill(一次性) ```bash curl -fsSL https://company-deploy-mcp.loncode.site/install-skill.sh | bash # 或 npx skills add http://git.loncode.site/Buxi/company-deploy-skills.git --skill dokploy-gitea-deploy -g -y ``` Skill 只定义流程;**没有配置 MCP + `buxi_` Key 则无法部署**。 --- ## 2. 联通性检测(每次部署前必做) 按顺序,**先测再部署**。任一步失败:按 §6 处理,**禁止**改口去要 Dokploy。 ### 2.1 MCP 是否挂上 Agent 能否调用 `company-deploy` 的工具(至少 `whoami`)。 | 结果 | 含义 | 下一步 | |------|------|--------| | 工具列表里有 `whoami` / `apply_deployment_plan` | 已配置 MCP | → 2.2 | | 没有这些工具 / 调用直接失败 | 未配置或 Key 错误 | → §3 鉴权 | ### 2.2 身份 ```text whoami ``` 期望字段示例:`role`(`user`|`admin`)、`openId`、`name`、`isAdmin`。 | 结果 | 处理 | |------|------| | 返回身份 JSON | 联通成功 | | 401 / Unauthorized / invalid token | Key 无效 → §3 | | 超时 / 连接失败 | 网络或控制面宕机 → 告之稍后重试,可 `curl -sS https://company-deploy-mcp.loncode.site/health` | ### 2.3 配额 ```text get_my_quota ``` 看运行中项目数是否达上限。满了:先 `list_projects`,让用户停/删不用的,**不要**绕过 MCP。 ### 2.4(可选)已有项目 ```text list_projects ``` 重部署时记下已有 `repo` + `environment`(部署标签,默认多为 `default`),**必须沿用**,禁止擅自改成 `production`。 --- ## 3. 鉴权与获取授权 ### 3.1 用户怎么拿 Key(业务同学) 1. 浏览器打开:**https://company-deploy-mcp.loncode.site/** 2. **飞书登录** 3. 复制页面上的 **`buxi_…` Key** 与 MCP 配置片段 4. 粘贴到 Agent 的 MCP 配置(见下) 5. 回到对话说「已配置」或直接「部署」 ### 3.2 Agent / 客户端怎么配 ```json { "mcpServers": { "company-deploy": { "url": "https://company-deploy-mcp.loncode.site/mcp", "headers": { "Authorization": "Bearer buxi_用户从连接中心复制的Key" } } } } ``` - 前缀:`buxi_`(旧 `cdp_` 可能仍可用,新发一律 `buxi_`) - **禁止**把 Key 写进业务 Git 仓库 - **禁止**把 Key 完整打印在对用户的回复里(可确认「已配置」) ### 3.3 权限模型(Agent 必须理解) | 能力 | 谁有 | 说明 | |------|------|------| | 部署自己的项目 | 任意有效 `buxi_` | 首次 `apply` 建立归属 | | 看自己的项目列表/状态 | 自己 | `list_projects` / `get_deployment_status` | | 看别人的项目 | 仅 admin | `ADMIN_OPEN_IDS` 或平台 `MCP_AUTH_TOKEN` | | 进 Dokploy 面板 | **不在本产品路径** | **禁止**当作用户解决办法 | | 手改 Gitea 权限 / SSH | **不需要** | 推送只用 `ensure_repository` 的 `pushUrl` | ### 3.4 鉴权失败怎么说(固定话术) **401 / 未配置 MCP:** > 还不能部署:需要先完成企业部署授权。 > 1. 打开 https://company-deploy-mcp.loncode.site/ > 2. 飞书登录,复制 `buxi_` Key > 3. 按页面说明粘贴到当前 Agent 的 MCP 配置 > 4. 配置好后回复「已配置」,我再继续部署。 > (连接中心只负责身份和 MCP,不需要 Dokploy 账号。) **403 看别人的项目:** > 当前账号只能管理自己名下的项目。如需管理员视角,请联系平台管理员把你的飞书 open_id 加入白名单。 **禁止话术(截图类错误):** - ❌「你不能通过项目网页进入 Dokploy」 - ❌「向管理员索取 Dokploy 面板地址 / 登录账号 / 某应用环境变量编辑权限」 - ❌「企业部署连接中心不是 Dokploy,所以你没法配 env——去找管理员开 Dokploy」 - ❌ 凭空编造 Dokploy URL 若用户要的是 **业务应用自定义密钥**(如第三方 API Key),而 plan 又注入不了: > 当前 MCP 会自动注入数据库连接(`databases[]`)和运行所需基础变量; > **不提供**业务同学自助打开 Dokploy 改 env。 > 可选:① 非密钥配置进代码/配置文件;② 密钥由平台管理员走运维通道注入(不经过业务 Dokploy 账号);③ 应用支持启动后自助配置页。 > **我不会让你去申请 Dokploy 面板权限。** --- ## 4. 部署操作流程(默认全链路) **前提:** §2 联通、§3 有有效 Key。工程为 **普通 Dockerfile** 服务(Python/Node/静态站等)。 妙搭/`@lark-apaas`:非主路径,见 `references/stack-profiles.md`;勿承诺与妙搭线上一致。 ```text ┌─────────────────────────────────────────────────────────────┐ │ A. 工程准备(本地) │ │ B. ensure_repository → pushUrl 推送(Agent,禁止用户 SSH) │ │ C. create_deployment_plan │ │ D. apply_deployment_plan ← 卷/库/域名/构建全在这里 │ │ E. 轮询 get_deployment_status / list_projects │ │ F. 探活 URL → 按 §5 回复用户 │ └─────────────────────────────────────────────────────────────┘ ``` 细节参数见 `references/mcp-deploy.md`;时序见 `references/sequence.md`。 ### 4.1 工程准备(Agent) - [ ] 有 `Dockerfile`,进程监听 **`0.0.0.0` + 容器端口**(与 plan `spec.port` 一致) - [ ] 有状态写 **`/data`**(或 `persistence[]` 声明的路径) - [ ] `.gitignore` 排除 `.env`、密钥、本地 db - [ ] 需要 PG/MySQL → plan 里 `databases: [{ "engine": "postgres", "envVar": "DATABASE_URL" }]` - [ ] Node 大前端:见 `stack-profiles.md`(禁止 install 前 `NODE_ENV=production`;堆内存;串行 multi-stage) ### 4.2 仓库与推送 ```text ensure_repository({ repo: "项目名" 或 "Buxi/项目名" }) → 使用返回的 agentHint.pushUrl(内含企业机器人 Token) → git add / commit → git push --set-upstream "" HEAD: → 记录 commitSha(git rev-parse HEAD) ``` | 硬规则 | | |--------|--| | 必须用 `pushUrl` 推 | 不要用无 Token 的 `origin` | | 禁止要用户配 SSH / 加公钥到 Gitea | 失败则重取 `ensure_repository`,查网络 | | 禁止把 `pushUrl` 全文贴给用户 | | ### 4.3 建计划 ```text create_deployment_plan({ repo, commitSha, # 已在 Gitea 上 branch: "main", environment: "default", # 除非用户明确要第二套并行环境 spec: { buildType: "dockerfile", dockerfilePath: "Dockerfile", buildPath: "/", port: <容器端口>, healthcheckPath: "/", exposeWeb: true # persistence / databases 按需 } }) → 记下 planId ``` **部署标签 `environment`:** 控制面 mapping 键,**不是** Dokploy 的 preview/production 分组。 默认 **`default`**。禁止因用户说「上线/生产」就改成 `production`。 ### 4.4 发布 ```text apply_deployment_plan({ planId }) ``` 控制面内部(Agent **不要**再做):挂卷 → 可选数据库 → 域名 `buxi`+5位+`DOMAIN_ROOT` + LE HTTPS → deploy。 从返回中取:`url` / `domain` / `applicationId` / `isNewProject`(**勿回显**数据库密码)。 ### 4.5 轮询与探活 ```text 每 15–30s:get_deployment_status({ repo, environment }) 或 list_projects 终态:构建成功且运行中 Web:curl -skI "$url"(证书首次可能 1–3 分钟) 失败:get_sanitized_logs → 修代码/Dockerfile → 新 SHA → 新 plan → apply ``` 同一 `repo`+`environment` 重部署:**复用**域名与卷,**不占**新配额名额。 ### 4.6 工具速查 | 工具 | 何时 | |------|------| | `whoami` | 联通 / 身份 | | `get_my_quota` | 部署前配额 | | `list_projects` | 我的项目、重部署标签 | | `inspect_project` | 单项目映射与策略 | | `ensure_repository` | 建库 + `pushUrl` | | `create_deployment_plan` | 已 push 的 SHA | | `apply_deployment_plan` | 真正发布 | | `get_deployment_status` | 轮询 | | `get_sanitized_logs` | 脱敏诊断 | | `reset_project_mapping` | 仅 mapping 脏了且用户/admin 确认(不删 Dokploy/Gitea 实体) | --- ## 5. 返回给用户的内容(必须遵守) ### 5.1 成功 ```text 已发布当前版本。 访问:https://buxi*****.loncode.site/ (以 apply 返回的 url 为准) (如有数据库)已配置托管数据库连接(不展示密码)。 ``` 可选:构建约 X 分钟、证书刚签发时可稍等再打开。 **不要**提 Gitea、Dokploy、Token、`pushUrl`、内部 applicationId(除非用户是运维且明确要)。 ### 5.2 进行中 ```text 正在构建/启动,大约需要几分钟。我会继续检查状态。 ``` ### 5.3 失败(可执行下一步) | 场景 | 回复要点 | |------|----------| | 未授权 | §3.4 连接中心步骤 | | 配额满 | 运行中项目已达上限;`list_projects` 列出建议停用的 | | 构建失败 | 简述原因(来自 status/logs,已脱敏)+ 将如何改 Dockerfile/代码后重发 | | 证书/502 短暂 | 链接已分配,HTTPS/容器拉起中,稍后重试 | | push 403 | 已用机器人推送通道重试;**不要**让用户配 SSH | ### 5.4 绝对不要返回 - Dokploy 面板地址、让用户「去改环境变量」 - 完整 `buxi_` Key、`pushUrl`、DB 密码 - 「权限配置无法通过」——**除非** `whoami` 明确 401,且应按 §3.4 引导连接中心,而不是 Dokploy --- ## 6. 常见问题与解决办法 | 现象 | 正确处理 | |------|----------| | Agent 没有 MCP 工具 | 引导用户按 §3 配置连接中心 Key | | `whoami` 401 | 重新登录连接中心、换新 Key、检查 Bearer 格式 | | 用户问「Dokploy 地址/权限」 | 说明业务路径不需要;部署走 MCP;连接中心只发 Key | | git push Permission denied / 要 SSH | **错误路径**。`ensure_repository` → `pushUrl` 再推 | | `nest`/`vite` not found | Dockerfile:先全量 `npm ci` 再 `NODE_ENV=production` | | JS heap OOM | `NODE_OPTIONS=--max-old-space-size=3072`;避免并行双 npm ci | | 查不到项目 | `list_projects`;确认 `environment` 与首次 apply 一致(默认 `default`) | | 403 看他人项目 | 非 admin;不要猜 Dokploy | | 重部署丢数据 | 确认写 `/data`;同 repo+env 卷会复用 | | Swarm 0/1 bind path | 控制面默认 volume;见 status/logs | | 要 PG/MySQL | plan `databases[]`,应用读 `DATABASE_URL` | | 业务要自定义密钥 | §3.4 末段;**禁止**引导 Dokploy 改 env | | 妙搭模板白屏/平台 API | 非主路径;`stack-profiles`;勿堆网关适配 | | `FORCE_AUTHN_*` 启动失败 | apply 会注入 boot env;不等于业务可用 | --- ## 7. 意图路由(用户一句话 → 动作) | 用户说法 | Agent 动作 | |----------|------------| | 部署 / 上线 / 发布 | §2 → §4 全链路 → §5 交付 URL | | 再发一版 / 重试 | push 新 SHA → create+apply(同 environment)→ 轮询 | | 我的项目 / 链接 | `list_projects` / `get_deployment_status` | | 配额 | `get_my_quota` | | 连不上 / 没权限 | **只**走 §2–§3(连接中心),**禁止** Dokploy | | 运维直连 Dokploy | 仅用户**明确**要求且本机有 `.env.deploy` → §8 | | 妙搭应用 | 先边界说明;优先 `lark-apps`;自托管实验见 stack-profiles | --- ## 8. Legacy:直连 Dokploy(运维例外 · 默认关闭) **仅当**同时满足: 1. 用户明确说「不要 MCP / 运维直连 Dokploy」;且 2. 本机有 `.env.deploy` + `DEPLOY_AUTHORIZED=true` 才可直连 Dokploy API。模板见 `references/env-deploy.example`。 **有 MCP 时禁止向业务要 `DOKPLOY_API_KEY`。** 默认对话 **不要** 提 Dokploy 面板。 --- ## 9. 支持范围(产品收口) | 栈 | 状态 | |----|------| | 普通 Python / Node / 静态站 + Dockerfile | **支持**(主路径) | | 自管登录与 DB 的 API | **支持** | | 飞书妙搭 / `@lark-apaas/*` | **实验性**;不承诺登录/平台 API;见 `stack-profiles.md` | 主路径承诺:Dockerfile + 端口 + `/data` + 可选库 → **HTTPS 链接**。 不承诺:模拟妙搭网关、业务自定义 env 面板、用户进入 Dokploy。 --- ## 10. 参考文件 | 文件 | 内容 | |------|------| | `references/mcp-deploy.md` | 工具参数、JSON 示例、apply 内部顺序 | | `references/sequence.md` | 时序图 | | `references/domain.md` | 域名与 HTTPS | | `references/stack-profiles.md` | Dockerfile 约定 + 支持矩阵 | | `references/env-deploy.example` | 仅 legacy | 线上: - 连接中心:https://company-deploy-mcp.loncode.site/ - MCP:https://company-deploy-mcp.loncode.site/mcp - 技能仓:http://git.loncode.site/Buxi/company-deploy-skills --- ## 11. Agent 出发前检查清单 - [ ] 已 `whoami` 成功(不是假设有权限) - [ ] 未要求用户打开 Dokploy / 提供面板账号 - [ ] 未索要 `DOKPLOY_API_KEY` / 用户 SSH - [ ] Dockerfile + port + `/data`(及可选 databases) - [ ] `ensure_repository` + **pushUrl** 推送 + `commitSha` - [ ] `environment` 默认 `default` 或与历史一致 - [ ] `apply` 后轮询并交付 **HTTPS url** - [ ] 回复符合 §5(无密钥、无 Dokploy 推诿)