Files
company-deploy-skills/dokploy-gitea-deploy/SKILL.md
2026-07-31 20:45:20 +08:00

315 lines
12 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.

---
name: dokploy-gitea-deploy
description: >
企业项目部署:默认走 company-deploy-mcp飞书身份 + buxi_ Key → 推 Gitea → MCP 建库/多卷/PG·MySQL/域名/HTTPS → 轮询)。
旧路径为直连 Dokploy API.env.deploy仅运维/无 MCP 时使用。触发词部署、上线、Dokploy、Gitea、
redeploy、MCP 部署、buxi_、company-deploy-mcp。Use when /dokploy-gitea-deploy。
metadata:
short-description: "企业部署:优先 MCP兼容 Dokploy 直连"
---
# 安装(给用户 / Agent
```bash
# 内网一键(推荐)
curl -fsSL https://company-deploy-mcp.loncode.site/install-skill.sh | bash
# 或 skills CLI
npx skills add http://git.loncode.site/Buxi/company-deploy-skills.git --skill dokploy-gitea-deploy -g -y
```
技能仓http://git.loncode.site/Buxi/company-deploy-skills
连接中心(飞书 + MCP Keyhttps://company-deploy-mcp.loncode.site/
Skill 只提供流程;真正部署还需配置 MCP `company-deploy``buxi_` Bearer
---
# 企业部署编排Gitea + Dokploy + company-deploy-mcp
业务同学不碰平台细节。Agent 负责:可构建工程 → 推代码 → 调控制面 → 交付 **HTTPS 链接**
**默认路径company-deploy-mcp必须优先。**
直连 Dokploy API 为 **legacy / 运维例外**
参考:
- `references/mcp-deploy.md`**MCP 默认状态机**(工具参数、域名/卷/库)
- `references/domain.md` — 域名与 HTTPSLets Encrypt无需通配符证书
- `references/sequence.md` — 时序
- `references/env-deploy.example` — 仅 legacy 直连用
- `references/stack-profiles.md` — Dockerfile 约定
线上连接中心:`https://company-deploy-mcp.loncode.site/`
MCP endpoint`https://company-deploy-mcp.loncode.site/mcp`
---
## 路径选择
| 条件 | 路径 |
|------|------|
| Agent 已配置 MCP `company-deploy``buxi_` Key | **MCP 默认** |
| 用户已飞书登录拿过 Key | **MCP 默认** |
| 用户明确「不要 MCP / 运维直连 / 改 Dokploy 底层」 | legacy |
| 无 MCP 且无 `.env.deploy` | **先引导连 MCP**,不要伪造部署 |
**禁止**在可用 MCP 时仍让业务填写 `DOKPLOY_API_KEY` / Gitea Token。
---
## 架构(默认)
```text
用户:「部署 / 上线」
→ AgentDockerfile + 本地验证
→ Agentensure_repositoryMCP→ 拿到 agentHint.pushUrl机器人 Token
→ Agentgit push <pushUrl>(禁止用用户 SSH禁止向用户要密钥
→ Agentcreate_deployment_plan + apply_deployment_plan
MCP 内部:挂卷 → PG/MySQL可选→ domainbuxi+5位.根域 + LE HTTPS→ deploy
→ Agentget_deployment_status / list_projects 轮询
→ 交付https://buxi*****.loncode.site + 脱敏说明
```
- **飞书**:身份;**buxi_ Key**:调用 MCP
- **Gitea**:源码(**gitea-robot** 建仓+推送;业务用户**不需要** Gitea 账号或 `~/.ssh`
- **Dokploy**:构建运行(由 MCP 调用,不直暴露给业务)
- **归属 / 配额 / 审计**:控制面 SQLite`owner_open_id`、运行中数量)
---
## 前置条件
### MCP 路径(默认)
1. 用户已在连接中心飞书登录Agent 已配置:
```json
{
"mcpServers": {
"company-deploy": {
"url": "https://company-deploy-mcp.loncode.site/mcp",
"headers": {
"Authorization": "Bearer buxi_..."
}
}
}
}
```
2. 项目有可构建 **Dockerfile**(进程监听 `spec.port`,状态写 `/data` 等挂载点)
3. 本机有 `git` 即可;**推送凭据来自 `ensure_repository``agentHint.pushUrl`****不要**配置用户 SSH、**不要**加 `id_ed25519.pub` 到 Gitea
4. 企业侧已配:`*.DOMAIN_ROOT` DNS → Dokploy80/443 可达Lets Encrypt
无 Key引导打开连接中心登录**不要**继续直连 Dokploy。
### Legacy 路径(运维)
见文末;需 `.env.deploy` + `DEPLOY_AUTHORIZED=true`
---
## MCP 标准状态机(必须按序)
细节与 JSON 示例见 `references/mcp-deploy.md`
### 0. 身份
- 调用 `whoami`(可选):确认 `role` / `openId`
- 调用 `get_my_quota`:看运行中数量是否达上限
### 1. 工程
- 识别栈;保证 Dockerfile`.gitignore` 排除密钥
- 有状态:默认 `/data`;多目录用 `persistence[]`
- 需要库:`databases: [{ engine: "postgres"|"mysql", ... }]`
- **Node 多阶段硬规则**(详见 `stack-profiles.md`
- 禁止在 `npm ci`/`pnpm install` **之前** `ENV NODE_ENV=production`(否则 `nest`/`vite` not found
- 大前端 Vite`NODE_OPTIONS=--max-old-space-size=3072`
- runtime 用 `COPY --from=build` 串行,避免并行双 `npm ci` 把小机打爆
### 2. 仓库与推送(权限红线)
```text
ensure_repository({ repo: "owner/name" 或 "name" })
→ 使用返回的 agentHint.pushUrl含企业机器人 Token
→ git add / commit
→ git push --set-upstream "<pushUrl>" HEAD:<defaultBranch>
→ 记录 commitSha
```
**硬规则:**
1. **禁止**要求用户上传/配置 `~/.ssh/id_ed25519.pub` 或任何个人 SSH Key。
2. **禁止**让用户自己去 Gitea 开权限、建仓、加 Collaborator。
3. **禁止**用未认证的 `cloneUrl``git push`(会 403 / Permission denied
4. **必须**用 `agentHint.pushUrl` 做一次推送;**不要**把 `pushUrl` 全文贴进对用户的回复。
5. 若仍 403重新 `ensure_repository` 取新 hint检查本机网络能否访问 `git.loncode.site`——**不要**改去配用户 SSH。
### 3. 计划与发布
```text
create_deployment_plan({
repo, commitSha, branch,
# environment = 控制面「部署标签」,默认 default。禁止擅自 invent production/staging
# 除非用户明确说「再部署一套并行环境」。与 status/redeploy 必须同一标签;不确定 list_projects
environment: "default",
spec: {
buildType: "dockerfile",
dockerfilePath: "Dockerfile",
buildPath: "/",
port: <容器端口>,
healthcheckPath: "/",
persistence: [ /* 可选多卷;缺省自动加 /data */ ],
databases: [ /* 可选 postgres|mysql */ ],
exposeWeb: true
}
})
→ apply_deployment_plan({ planId })
→ 使用返回的 url / domain / databases密码已脱敏
```
**环境概念(易混):**
| 名称 | 是什么 | 谁决定 |
|------|--------|--------|
| Dokploy Environment | 应用建在平台哪个分组(如 preview | 控制面 `DOKPLOY_ENVIRONMENT_ID`(全站统一) |
| MCP `environment` | 部署标签,`repo+标签` 对应一套应用/域名 | Agent 参数,默认 `default`,全公司应统一 |
已有项目若当初用了非 default 标签,重部署/查状态必须继续传该标签,不要擅自改(否则会当成新项目)。
### 部署标签硬规则Agent
1. **默认且优先**:省略 `environment` 或显式 `"default"`
2. **禁止**仅因用户说「上线 / 生产 / 正式」就改成 `production`——那只是业务话术,不是部署标签。
3. **仅当**用户明确要求「第二套环境 / staging / 并行预发」时,才用非 default 标签。
4. 重部署前 `list_projects`,沿用已有 `environment` 字段。
### 4. 轮询与交付
```text
get_deployment_status / list_projects
Webcurl -skI "$url" 或健康路径(证书可能短暂签发中)
```
对用户:
-**HTTPS 链接**`apply``url`
- 不提 Gitea/Dokploy/Token
- 配额满、无权:原文转述 MCP 错误
### 5. 域名与 HTTPS控制面完成Agent 勿重复 domain.create
- 默认 host`buxi` + 5 位随机 `[a-z0-9]` + `.` + `DOMAIN_ROOT`
例:`buxi3k9xa.loncode.site`
- 首次分配后 **固定**(存在控制面 mapping
- HTTPSDokploy Traefik + **Lets Encrypt 按子域签证书****不需要**通配符证书)
- DNS建议 `*.loncode.site` → 服务器(通配 **解析**,不是通配证书)
- 证书失败:查 80/443、DNS可暂 HTTP 仅当控制面 `DOMAIN_HTTPS=false`
Agent **不要**在 MCP 路径下再调 Dokploy `domain.create`(避免双绑/冲突)。
### 6. 卷与数据库
| 能力 | 行为 |
|------|------|
| 默认卷 | Docker named volume → `/data`(避免 bind 目录不存在导致 Swarm 0/1 |
| bind 模式 | 可选;控制面 mkdir 宿主机路径,失败回退 volume |
| 多卷 | `spec.persistence[]`;缺 `/data` 仍自动补 |
| Postgres / MySQL | `spec.databases[]` → Dokploy 建库 + 注入 `DATABASE_URL` 等 |
| 重部署 | 同 repo+env 不占新配额名额;域名与库记录复用 |
应用必须把状态写在挂载路径(如 SQLite → `/data/app.db`)。
---
## 意图路由
| 用户说法 | 动作 |
|----------|------|
| 部署 / 上线 / 第一次发布 | MCP 全链路;交付 `url` |
| 重试 / 再构建 | 新 SHA → 新 plan → apply已有 mapping |
| 查状态 / 我的项目 | `list_projects` / `get_deployment_status` |
| 配额 | `get_my_quota` |
| 只要链接 | `list_projects``url`;无则查 status |
| 运维直连 Dokploy | 仅明确要求时走 legacy |
---
## 对用户话术
**成功:**
- 已发布当前版本
- 访问:`https://buxi….loncode.site/`(以 MCP 返回为准)
- 需要库时:说明已注入数据库连接(**不打印密码**
**失败:**
- 配额满 / 未登录 Key / 构建失败 / 证书签发中
- 给可执行下一步,不暴露平台密钥
---
## 安全红线
1. 永不 commit / 回显:`buxi_` Key、`MCP_AUTH_TOKEN`、Dokploy/Gitea Token、`pushUrl`、数据库密码全文
2. `apply` 返回的 `connectionUrl` 已脱敏则保持;未脱敏则遮罩
3. 普通用户不可查他人项目(控制面会 403
4. 生产破坏性操作仍受控制面策略约束
5. **禁止**因 push 失败引导用户配置个人 SSH那是错误路径
---
## Agent 检查清单MCP
- [ ] MCP 可用;`whoami` 正常
- [ ] Dockerfile + 数据写挂载点
- [ ] `ensure_repository` + push + `commitSha`
- [ ] plan 含正确 `port`;需要时 `persistence` / `databases`
- [ ] `apply` 拿到 `url`
- [ ] 轮询至终态;探活
- [ ] 未向用户索要 Dokploy/Gitea 地址或 Token
---
## Legacy直连 Dokploy运维例外
**仅当**用户明确要求或 MCP 不可用且有 `.env.deploy`
1. `set -a && source .env.deploy && set +a``DEPLOY_AUTHORIZED=true`
2. 按旧流程Dockerfile → push → `application.*` / `mounts` / `domain.create` / deploy
3. 域名规则见 `references/domain.md` **Legacy** 段(与 MCP 的 `buxi+5` 规则不同,勿混用)
4. 模板:`references/env-deploy.example`
5. 仍禁止把密钥贴进聊天
**默认对话不要走这条。** 有 MCP 时禁止向业务索要 `DOKPLOY_API_KEY`
---
## 与其它 skill 边界
| 场景 | 用 |
|------|-----|
| 企业 Dockerfile 部署(默认) | **本 skill → MCP** |
| 妙搭云端发布 | `lark-apps` |
| 无 MCP 的运维救火 | 本 skill → legacy |
---
## 故障速查MCP
| 现象 | 处理 |
|------|------|
| 401 / 要 Feishu Key | 引导连接中心登录,配置 `buxi_` |
| git push 权限 / Permission denied / 要配 SSH | **错误路径**。改用 `ensure_repository``agentHint.pushUrl` 推送;禁止给用户配 SSH |
| `nest: not found` / `vite: not found` | build 阶段在装依赖前设了 `NODE_ENV=production`;先全量 `npm ci` 再设 production |
| `JavaScript heap out of memory` | Dockerfile build 加 `NODE_OPTIONS=--max-old-space-size=3072`;避免并行 npm ci机器内存过小则升配 |
| `FORCE_AUTHN_INNERAPI_DOMAIN` / 平台模式需要基础域名 | 妙搭模板自部署缺 env控制面 apply 会注入;老应用再 apply 或 Dokploy 手动补公网 URL |
| 运行中项目达上限 | `get_my_quota`;停/删旧应用后再部署 |
| Forbidden 看他人项目 | 非管理员;加 `ADMIN_OPEN_IDS` 或只查自己的 |
| 有部署无 HTTPS | 等 LE查 DNS/80控制面证书配置 |
| 重部署丢数据 | 确认写 `/data`;控制面默认挂载是否开启 |
| Swarm 0/1 + bind path does not exist | 控制面已默认 volume + mkdir旧应用可 `mkdir -p` 宿主机路径或删 bind 改 volume 后 redeploy |
| 要 PG/MySQL | plan 里带 `databases`,勿手建后不注入 env |