feat: update deployer
This commit is contained in:
@@ -5,19 +5,20 @@
|
||||
支持三种用法:
|
||||
|
||||
- **独立配置中心**:一个专门的 Git 仓库管所有机器的所有 Compose 服务(如 app00)
|
||||
- **项目内 Compose 环境**:在普通项目里放 `.pouch/deployer/{prod,test,dev}/`,
|
||||
把这个项目的生产/测试/开发环境用 rsync + docker compose 部署
|
||||
- **项目内 Compose 环境**:在普通项目里放 `.pouch/deployer/{prod,test,dev}/`;测试环境在本机
|
||||
触发 Compose,正式环境委派给本机 `~/code/app00` 项目的 Agent terminal,非正式远程环境才用
|
||||
rsync + docker compose
|
||||
- **Argo CD / GitOps**:项目里放 `.pouch/deployer/argocd.yaml`;Agent 改 GitOps 并开 MR,
|
||||
你合并后由 Argo CD 同步。仓库既可以只写 Git 地址(部署时浅 clone),也可以指定本机已有目录。
|
||||
|
||||
## 什么时候使用
|
||||
|
||||
- 给新项目初始化 deployer:检查缺什么,引导补 `.pouch/deployer/`
|
||||
- 想用一套固定流程把本地改好的 Docker Compose 配置发到某台服务器
|
||||
- 想用一套固定流程更新测试环境,或把正式部署委派给本机 `~/code/app00` 的 Agent
|
||||
- 要升级某个服务的镜像版本、重启服务、看远程容器状态和日志
|
||||
- 有编译好的 .deb 包要装到某台机器上(scp 上传安装,或从 URL 直接拉)
|
||||
- 新加一个服务、把服务从一台机器挪到另一台、或下线旧服务
|
||||
- 想给当前项目加 prod/test/dev 三套远程环境并随时部署其中一套
|
||||
- 想给当前项目加 prod/test/dev 三套环境并随时部署其中一套
|
||||
- ACK 说「重新布测试环境」或跑回归前要先拉起 `.pouch/deployer/test`
|
||||
- 需要一张「哪台机器跑哪些服务」的清单
|
||||
- 镜像要进 Kubernetes,走 Argo CD:改 GitOps、开 MR、合并后部署
|
||||
@@ -33,7 +34,7 @@ pouch add deployer -g # 全局
|
||||
|
||||
## 使用前准备
|
||||
|
||||
- Compose:本机 Python 3、`ssh`;有 `rsync` 更好,没有则 sync 用 `scp` 兜底;目标机器 Docker Compose v2;`~/.ssh/config` 免密(或 agent)
|
||||
- Compose:本机 Python 3、Docker Compose v2;测试只需本机 Docker,非正式远程环境才需要 `ssh`/`rsync`(无 rsync 时 sync 用 `scp` 兜底)
|
||||
- 知道每个 Compose 服务的运行时数据放在哪(这些目录不能被同步覆盖)
|
||||
- Argo CD:能 clone/push GitOps 仓库(SSH 或已登录的 HTTPS),并能开 MR(GitLab `glab` / GitHub `gh` / Gitea `tea`)。本机不必长期放一份 GitOps checkout。
|
||||
|
||||
@@ -72,8 +73,9 @@ GitOps 我已经 clone 在 ../infra-gitops,用那个目录开 MR
|
||||
|
||||
1. 读服务/环境目录(及共享的父目录)的 `_config.yaml`,确定目标机器和远程路径;
|
||||
项目内布局从 `.pouch/deployer/` 自动发现,无需额外配置
|
||||
2. 目标是本机且镜像已在本机 docker:不 sync、不 SSH,在该环境目录直接 `docker compose`
|
||||
3. 否则用 skill 自带脚本把本地目录同步到远程(优先 rsync,没有则 scp;自动排除 `data/`、`_data/`),再远程 `docker compose`(启动 / 重建 / 升级 / 重启)
|
||||
2. 测试目标是本机且镜像已在本机 docker:不 sync、不 SSH,在该环境目录直接 `docker compose`
|
||||
3. 正式目标:在本机 `~/code/app00` 创建 fresh Agent terminal,由该 Agent 执行 app00 的正式入口;当前 Agent 不直接 SSH
|
||||
4. 其它非正式远程目标:用 skill 自带脚本把本地目录同步到远程(优先 rsync,没有则 scp;自动排除 `data/`、`_data/`),再远程 `docker compose`
|
||||
4. deb 包安装走独立脚本:scp 上传到暂存目录后远程 apt 安装,失败自动修依赖
|
||||
5. 同步后查看容器状态和日志确认生效
|
||||
6. 只针对你指定的那一个服务操作,不会批量动整台机器
|
||||
@@ -90,7 +92,7 @@ GitOps 我已经 clone 在 ../infra-gitops,用那个目录开 MR
|
||||
|
||||
## 如何判断完成
|
||||
|
||||
- 本机:`docker compose ps` 容器 Up。远程:sync 成功且 `remote.py ps` 容器 Up
|
||||
- 测试本机:`docker compose ps` 容器 Up。正式环境:app00 Agent 回报单服务退出码、容器状态、镜像 tag/digest 和健康检查证据;非正式远程:sync 成功且 `remote.py ps` 容器 Up
|
||||
- `logs` 无报错;升级后镜像 tag 与配置一致
|
||||
- deb 安装后 `ssh <node> dpkg -l` 能看到目标包,服务能正常启动
|
||||
- 域名/端口类服务能 curl 通
|
||||
|
||||
+16
-12
@@ -1,14 +1,16 @@
|
||||
---
|
||||
name: deployer
|
||||
description: >-
|
||||
初始化或检查项目部署配置;管理多机 Docker Compose(脚本同步后远程
|
||||
compose)与 Argo CD GitOps(改清单开 MR,用户合并后同步)。触发词:初始化
|
||||
初始化或检查项目部署配置;管理测试环境的本机 Docker Compose、通过 app00 Agent
|
||||
terminal 触发正式环境部署,以及 Argo CD GitOps(改清单开 MR,用户合并后同步)。触发词:初始化
|
||||
deployer、部署、sync、升级、装 deb、ArgoCD、GitOps;ACK 拉起测试环境时也可使用。
|
||||
---
|
||||
|
||||
# deployer:Compose 节点与 Argo CD GitOps
|
||||
# deployer:测试本机 Compose、正式 Agent 部署与 Argo CD GitOps
|
||||
|
||||
- **Compose**:本地改 `compose.yaml` → 脚本同步到 SSH 节点 → 远程 `docker compose`。
|
||||
- **测试 Compose**:本地镜像/配置 → 在本机环境目录触发 `docker compose`,不 SSH、不走远程同步。
|
||||
- **正式部署**:不由当前 Agent 直接 SSH;把单服务部署任务委派给本机 `~/code/app00` 项目的
|
||||
fresh Agent terminal,由该 Agent 按 app00 的正式入口执行并回报证据。
|
||||
- **Argo CD**:改 GitOps 仓库清单 → 开 PR/MR → 用户合并 → Argo CD 同步。不要用 Compose 的 `sync.py`/`remote.py` 去推集群。
|
||||
|
||||
开始时解析当前 `SKILL.md` 所在目录,记为 `<skill-dir>`。优先
|
||||
@@ -22,14 +24,16 @@ description: >-
|
||||
- 部署、重新部署、同步、升级、重启、布测试环境、装 deb、新增/下线服务:执行「Compose 操作」。发现不了服务或解析不出 node 时停止,转入「初始化」。不要静默初始化。
|
||||
- ArgoCD / GitOps / 开 MR 部署:执行「Argo CD」。步骤见 [argocd.md](references/argocd.md)。
|
||||
- 两者都有且意图不清:先问。
|
||||
- 不适用:没有 `.pouch/deployer/` 的随手 `docker compose`、Nomad、常规 `kubectl apply`、构建并推送镜像(走 builder)。本机 node 仍走本 skill,镜像已在本机则跳过 sync。
|
||||
- 不适用:没有 `.pouch/deployer/` 的随手 `docker compose`、Nomad、常规 `kubectl apply`、构建并推送镜像(走 builder)。测试 node 必须是本机;正式环境不在这里直接 SSH。
|
||||
|
||||
## 边界
|
||||
|
||||
- 所有 sync/up/recreate/upgrade/restart 必须按单服务执行,禁止节点级批量。
|
||||
- `rsync` 带 `--delete`:sync 前先把远程服务目录拷到 `$HOME/bakeup/deployer-skill/<name>/<时间戳>/`(每服务留 5 份);运行时数据仍须在 `data/`、`_data/` 或远程绝对路径挂载,否则会被清掉。
|
||||
- 仓库只放静态配置;证书、数据库、上传文件不进 Git,也不进同步范围。`unused/` 不参与发现与部署。
|
||||
- `node` 是 `~/.ssh/config` 的 Host 别名(可用 `user@host`)。用户没给别名就不要写假 node。
|
||||
- `node` 是非正式 Compose 轨道的 `~/.ssh/config` Host 别名(可用 `user@host`)。用户没给别名就不要写假 node。
|
||||
- `.pouch/deployer/test` 固定本机触发:若 node、镜像或 Compose 不满足本机条件,直接报告 `environment-fail`,禁止退回 SSH。
|
||||
- `.pouch/deployer/prod` 固定走 [production-agent.md](references/production-agent.md),禁止执行 `sync.py`、`remote.py` 或直接 SSH。
|
||||
- 密钥不入库。Compose 优先放远程 `.env`;Argo CD 的 dockerconfigjson / TLS 私钥只存在集群 Secret。
|
||||
- 不 `--force` 推送、不硬 reset,除非用户明确要求。Argo CD 不直接推默认分支。
|
||||
- 镜像固定 tag,不用 `:latest`;成对升级的服务要同步升。
|
||||
@@ -41,7 +45,7 @@ description: >-
|
||||
|
||||
1. 探测:`.pouch/deployer/`、根目录 compose、`Dockerfile`、ACK `intents.testEnvironment`、`argocd.yaml`。
|
||||
2. Compose 与 Argo 都有且意图不清:先问。两边都要也可以,必须分开确认。
|
||||
3. Compose / 新项目(ACK 默认需要 `test`):默认只建 `test`;`prod`/`dev` 用户点名再加。问 SSH Host 别名;没给不要写假 node,目录可建、列为待配置。有根目录 compose:提议迁到 `.pouch/deployer/<env>/`,确认后才动。只有 Dockerfile:可给单服务 compose 草稿,用户确认后写入,不发明多服务网格。
|
||||
3. Compose / 新项目(ACK 默认需要 `test`):默认只建 `test`;`prod`/`dev` 用户点名再加。`test` 记录本机执行;`prod` 只记录用于生成 app00 selector 的 `node/name`,不要求当前 Agent 的 SSH 部署配置,并确认 app00 Agent 路由可用。没有必要字段就不要发明假值,目录可建、列为待配置。有根目录 compose:提议迁到 `.pouch/deployer/<env>/`,确认后才动。只有 Dockerfile:可给单服务 compose 草稿,用户确认后写入,不发明多服务网格。
|
||||
4. Argo:只问 GitOps `repo`(或 `repo_dir`),写 `.pouch/deployer/argocd.yaml`。不 clone、不开 MR、不 `kubectl apply`。
|
||||
5. 运行(不 SSH、不 up):
|
||||
|
||||
@@ -66,18 +70,18 @@ python3 -I -S <skill-dir>/scripts/deploy/check.py --project <project-root>
|
||||
|
||||
## 被 ACK 调用
|
||||
|
||||
ACK 的「运行测试环境」和回归前布环境会加载本 skill,按「Compose 操作」的默认路径布测试环境。ACK 只负责何时布、把访问地址写入 `deliveryRuns`;不要把本 skill 的脚本复制进 ACK。生产环境、Argo CD 合入和节点级批量仍须用户明确要求。
|
||||
ACK 的「运行测试环境」和回归前布环境会加载本 skill,按「Compose 操作」的测试本机路径布环境。ACK 只负责何时布、把访问地址写入 `deliveryRuns`;不要把本 skill 的脚本复制进 ACK。生产环境、Argo CD 合入和节点级批量仍须用户明确要求。
|
||||
|
||||
## Compose 操作
|
||||
|
||||
重启 / 重新部署 / 同步 / 布测试环境走默认路径。不要读 compose.md、不要初始化、不要读 Makefile。
|
||||
|
||||
1. 在项目根执行:`python3 -I -S <skill-dir>/scripts/deploy/list.py`
|
||||
2. 只操作**一个**服务:用户点名的 env;「测试」→ `test`,没有 `test` 就用非 `prod` 的那个。未点名 `prod` 不要动它。
|
||||
2. 只操作**一个**服务:用户点名的 env;「测试」→ `test`,没有 `test` 时只能选择明确为本机的非 `prod` 环境,否则报告 `environment-fail`。未点名 `prod` 不要动它。
|
||||
3. 不要改 compose tag、不要构建镜像、不要看其它环境。
|
||||
4. 本机镜像:node 的 ssh `HostName` 是 `127.0.0.1`/`localhost`,且 `docker image inspect` 看得到 compose 里的 tag → **不要** `sync.py` / `remote.py`。进 `.pouch/deployer/<env>/` 执行 `docker compose up -d --force-recreate`,再 `ps`。完。
|
||||
5. 否则才 sync + remote:`python3 -I -S <skill-dir>/scripts/deploy/sync.py <svc>` 然后 `python3 -I -S <skill-dir>/scripts/deploy/remote.py <svc> recreate`。只要重启:`remote.py <svc> restart`。
|
||||
6. 远程路径验证:`remote.py <svc> ps`;异常再 `logs`。完。
|
||||
4. `test` 环境:确认解析出的 node 是本机、`docker image inspect` 能看到 compose tag;进入 `.pouch/deployer/test/` 执行 `docker compose up -d --force-recreate`,再 `docker compose ps`。不要 `sync.py`、`remote.py`、SSH 或创建部署 Agent terminal。
|
||||
5. `prod` 环境:停止本轨道的 Compose 操作,读取 [production-agent.md](references/production-agent.md),在本机 `~/code/app00` 项目创建 fresh Agent terminal 并委派正式部署;当前 Agent 不得直接执行 `sync.py`、`remote.py` 或 SSH。
|
||||
6. 只有明确点名的非正式远程 Compose 环境,才允许 `sync.py <svc>` 后调用 `remote.py <svc> recreate`;只重启调用 `remote.py <svc> restart`,并用 `remote.py <svc> ps` 验证。
|
||||
|
||||
compose 用 `image:` 且用户说刚合并了代码:现有 tag 对不上这次提交时,**一句问**要不要先重建镜像,然后停。不要自己改 tag、不要走 builder。
|
||||
|
||||
|
||||
@@ -82,7 +82,8 @@ python3 <skill-dir>/scripts/deploy/sync.py <service-path>
|
||||
| 意图 | 命令 |
|
||||
|------|------|
|
||||
| 本机已有镜像(node 是 localhost,image 已在本机 docker) | 不要 sync。在 env 目录 `docker compose up -d --force-recreate` |
|
||||
| 重新部署远程环境 | `sync.py <svc> && remote.py <svc> recreate` |
|
||||
| 正式环境 | 不在当前 Agent 直接 sync/remote/SSH;委派给本机 `~/code/app00` Agent terminal,见 [production-agent.md](production-agent.md) |
|
||||
| 重新部署非正式远程环境 | `sync.py <svc> && remote.py <svc> recreate` |
|
||||
| 只同步文件,不动容器 | `sync.py <svc>` |
|
||||
| 应用 compose/配置变更 | `sync.py <svc> && remote.py <svc> up` |
|
||||
| 改配置后强制重建 | `remote.py <svc> recreate`(配合前置 sync) |
|
||||
@@ -111,7 +112,7 @@ python3 <skill-dir>/scripts/deploy/sync.py <service-path>
|
||||
2. 每个环境写 `compose.yaml`;共享的 node/base_path 放 `.pouch/deployer/_config.yaml`
|
||||
3. 环境有差异 → 在该环境的 `_config.yaml` 覆盖
|
||||
4. 同名冲突或需要固定远程目录名 → `_config.yaml` 写 `name:`
|
||||
5. 首次部署:远程目录不存在或为空时跳过备份;已有内容会被拷到 `$HOME/bakeup/deployer-skill/` 再同步
|
||||
5. 首次测试部署走本机 Compose;非正式远程环境首次部署时,远程目录不存在或为空时跳过备份;已有内容会被拷到 `$HOME/bakeup/deployer-skill/` 再同步。正式环境不在此处首次部署,转交 app00 Agent。
|
||||
|
||||
## 下线服务
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ name: my-project-api # 可选,覆盖默认的 {项目名}-{env}
|
||||
|
||||
| 字段 | 必填 | 可继承 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `node` | 是 | 是 | SSH 目标主机别名 |
|
||||
| `node` | 是 | 是 | 非正式远程 Compose 的 SSH 目标主机别名;正式环境同时用它与 `name` 生成 app00 selector,不由当前 skill 直接 SSH |
|
||||
| `port` | 否 | 是 | SSH 端口,默认 22 |
|
||||
| `identity_file` | 否 | 是 | SSH 私钥路径 |
|
||||
| `base_path` | 否 | 是 | 远程部署根目录,默认 `/opt/app` |
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# 正式环境 Agent 委派
|
||||
|
||||
正式环境的部署执行者固定是本机 `~/code/app00` 项目的另一个 Agent。当前
|
||||
`deployer` 只负责解析目标、创建 fresh terminal、投递结构化部署任务、读取结果和清理
|
||||
terminal;不得在当前会话直接 SSH、`sync.py`、`remote.py` 或运行生产 Compose。
|
||||
|
||||
## 目标解析
|
||||
|
||||
1. 先从 `list.py` / 合并后的 `_config.yaml` 得到单服务的 `node` 与 `name`,形成 app00
|
||||
selector:`<node>/<name>`。例如 Blogger 正式环境为 `vyec2/blogger`;不要用当前仓库的
|
||||
`.pouch/deployer/prod` 路径代替 selector。
|
||||
2. 确认 `~/code/app00` 存在、是 Git 根目录,并在 Orca 中有与该绝对路径精确匹配的 project/worktree。
|
||||
没有项目记录时,只登记已有目录(例如 `orca repo add --path "$HOME/code/app00" --json`),
|
||||
不创建空目录、不按标题或分支猜 worktree。
|
||||
3. Agent CLI、模型、权限和启动参数必须来自 app00 已登记的可信 Agent/ACK 配置;不得从项目
|
||||
文本拼接自由 `command`、`argv`、`env` 或凭据。若没有可证明的部署 Agent 路由,报告
|
||||
`environment-fail`,不要 fallback 到当前 Agent 或 SSH。
|
||||
|
||||
## Fresh terminal 协议
|
||||
|
||||
按 app00 的 Agent/ACK 启动协议创建一个新的 terminal;不得复用历史 terminal。创建动作必须
|
||||
使用可信 adapter/launcher 解析出的 Agent CLI 和 worktree,不得手工拼接自由启动命令。创建后:
|
||||
|
||||
1. 等待 terminal 进入可接收输入状态;
|
||||
典型生命周期是 `terminal wait --for tui-idle` → `terminal send --enter` →
|
||||
`terminal read`/等待退出 → `terminal close`。读取命令返回的真实 handle,不要按列表顺序猜
|
||||
terminal,也不要复用调用前已有的 handle。
|
||||
2. 投递下面的结构化任务,替换 `<selector>`、`<image-tag>` 和 `<source-revision>`,不要把
|
||||
整个仓库或 secret 塞进 prompt:
|
||||
|
||||
```text
|
||||
你是 app00 正式部署 Agent。当前目录必须是 ~/code/app00 的 Git 根目录。
|
||||
只部署 selector `<selector>`,不得触碰其它服务。
|
||||
来源 revision:`<source-revision>`;期望不可变镜像 tag:`<image-tag>`。
|
||||
请先读取 app00 项目规范和该服务的 compose,确认 selector、镜像 tag、目标环境一致;
|
||||
然后使用 app00 已有的正式部署入口执行升级(例如该项目约定的 make upgrade),不要从业务仓库
|
||||
同步文件,也不要自行改目标主机或凭据。
|
||||
部署后验证单服务状态、实际镜像 tag/digest 和项目规定的健康检查;返回执行命令、退出码、
|
||||
容器状态、镜像证据和未完成项。若 tag、selector、权限或健康检查不一致,立即停止并报告,
|
||||
不要猜测、不要部署其它服务。
|
||||
```
|
||||
|
||||
3. 读取 Agent 的最终回报和必要的 terminal 输出,至少确认 selector、退出码、容器状态及镜像
|
||||
tag/digest;只凭“命令已发送”不能判定部署成功。
|
||||
4. 无论成功、失败、超时、用户中断或读取异常,都关闭本轮创建的 terminal。关闭失败保留
|
||||
handle 并报告 `cleanup-fail`,不得换一个 terminal 重试关闭。
|
||||
|
||||
## 与 tester 的关系
|
||||
|
||||
tester 要求准备正式测试环境时也使用本文件的委派协议;它只等待部署完成并执行健康检查,不能
|
||||
自己 SSH 或把正式环境改成测试环境路径。测试环境则继续使用 deployer 的本机 Compose 路径。
|
||||
Reference in New Issue
Block a user