通过 aliyun appmanager 部署到阿里云 ECS
概述
aliyun appmanager 是面向 Agent 的 CLI 工具,用于将应用(App)和 AI Agent 一键部署到阿里云 ECS。它支持非交互模式(--non-interactive)、结构化 JSON 输出(--output json)和流式 NDJSON 响应。
默认行为:当用户调用 /alibabacloud-ecs-code-deploy 而未指定项目路径或 URL 时,将当前工作目录项目部署到阿里云 ECS。如果用户提供 git URL,先克隆到当前目录,然后 cd 进入克隆目录并继续部署。
执行顺序:Agent 必须遵循本文档底部「完整部署工作流」章节以获取正确的执行序列。下方 Task 章节按主题组织以供参考——其编号不代表执行顺序。
强制要求:开始前创建 Todo 列表
执行任何步骤之前,Agent 必须创建包含以下所有条目的 todo 列表。不要省略任何条目。在 todo 列表创建之前不要开始部署。
Todo 列表(部署到阿里云 ECS):
[ ] 0. 解析 $SKILL_DIR(跨平台路径 —— 必须首先运行;见下方「步骤 0」)
[ ] 1. 环境预检(必须运行 deploy_toolkit.py check;禁止用人工命令替代)
[ ] 2. 获取项目(如需要在此克隆 git URL;本地项目跳过)
── 检查 .appmanager/config.yaml 是否已存在(重复部署捷径) ──
│ 存在 + 新 ECS(无 instanceId) → 跳过 3-5,从 5.5(询价)开始
│ 存在 + 已有 ECS(有 instanceId) → 跳过 3-5.5,跳到 6(部署)
│ 不存在 → 从 3 正常继续
───────────────────────────────────────────────────────────────────────────────
[ ] 3. 读取项目(README.md -> 快速部署方法)+ 识别类型(agent / app)
[ ] 4. 询问用户部署配置(地域 + 新 ECS / 已有 ECS)
[ ] 5. 初始化 + 生成脚本(appmanager init -> 将启停脚本写入 config.yaml)
[ ] 5.5. 部署前询价 + 风险提示(必须运行 deploy_toolkit.py price;逐项确认价格 / OSS 计费 / 已有 ECS 影响 / 分组覆盖)
[ ] 6. 部署(必须运行 deploy_toolkit.py deploy;禁止用人工部署命令替代)
[ ] 7. 验证(必须运行 deploy_toolkit.py verify;禁止用人工状态命令替代)
[ ] 8. 输出最终结果(控制台链接 + 费用提醒 + 管理命令)
⛔ 脚本优先规则:步骤 1、5、6、7 在$SKILL_DIR/scripts/deploy_toolkit.py有专用工具脚本(其中$SKILL_DIR在下文步骤 0 中解析——适用于 Qoder、Claude Code 及任何其他平台)。Agent 必须直接运行对应子命令,作为该步骤的第一个且唯一动作——绝不在脚本之前或代替脚本运行人工 CLI 命令(如aliyun version、版本检查、凭证检查)。脚本已在内部处理所有检查。仅当脚本文件本身不存在时,才允许人工命令作为兜底。
❌ 错误(步骤 1):运行aliyun version→ 检查版本 → 运行~/.aliyun/appmanager-venv/bin/python ...→ 检查版本 → 然后才运行deploy_toolkit.py check
✅ 正确(步骤 1):运行python3 "$SKILL_DIR/scripts/deploy_toolkit.py" check→ 若退出码 1,修复其报告的问题 → 若脚本文件缺失,才回退到人工检查
条目 6 是不可协商的。跳过日志验证并直接输出"部署成功"的 Agent 未正确完成本 Skill。如果 deploy_toolkit.py verify 退出码 1(失败),Agent 必须在进入条目 7 之前修复问题并重新部署。
步骤 0(强制):解析 $SKILL_DIR —— 跨平台路径
工具脚本位于<skill-root>/scripts/deploy_toolkit.py。不同平台将 skills 安装到不同位置(Qoder/Claude Code/Qwen/...)。Agent 必须在会话开始时一次性解析 Skill 根目录的绝对路径,并在下文所有出现$SKILL_DIR处复用。禁止硬编码任何平台特定路径。
完整 10 候选检测算法、export + test -f 验证片段,以及 Pattern A / Pattern B / ⛔ 反模式使用规则,见 references/skill-dir-resolution.md。
快速回顾(详见参考):
- ✅ Pattern A(持久 shell):
export SKILL_DIR="/abs/path",之后python3 "$SKILL_DIR/scripts/deploy_toolkit.py" <sub> - ✅ Pattern B(每次调用新 shell):内联绝对路径 ——
python3 "/abs/path/scripts/deploy_toolkit.py" <sub> - ⛔ 反模式:
SKILL_DIR=/path python3 "$SKILL_DIR/..."—— 外层 shell 在前缀赋值之前展开$SKILL_DIR,产生/scripts/deploy_toolkit.py和 ENOENT。如果看到python3: can't open file '/scripts/deploy_toolkit.py',切换到 Pattern A 或 B。
任务 1:安装阿里云 CLI
主要动作:运行 python3 "$SKILL_DIR/scripts/deploy_toolkit.py" check —— 它一次性检查 CLI 版本 + appmanager-cli 版本 + 凭证。仅当脚本文件缺失时,才使用 references/init-and-credentials.md 中的兜底。
必须 —— 处理未满足的环境前置条件:当check因 aliyun CLI 缺失或低于 3.3.19(或 appmanager-cli 缺失 / 过旧)而以退出码 1 结束时,Agent 不得静默停止工作流。要求的流程是:
1. CLI 未安装 → 直接自动安装,无需询问用户 —— 执行安装命令(见下方片段或 references/init-and-credentials.md 选择正确架构),然后重新运行deploy_toolkit.py check确认。
2. CLI 已安装 → 先询问用户 —— 展示检测到的版本 + 要求版本 + 升级命令,并请求明确同意(例如"aliyun CLI 3.3.4 已安装但低于 appmanager 要求的 >= 3.3.19;批准升级(覆盖安装到 /usr/local/bin,需要 sudo)?")。绝不假设同意;绝不粘贴凭证。
- 批准后 —— 执行安装 / 升级命令,然后重新运行deploy_toolkit.py check确认。
- 拒绝后 —— 以该拒绝为原因停止。不要用旧版本继续(部署无论如何会失败)。
工具脚本的check输出已为每个可修复问题包含→ AGENT: DO NOT stop. ASK user ...行——逐字遵循("未安装"情况除外,它自动处理)。
必须 —— 升级方法优先级:brew 管理的 →brew upgrade(不要再次覆盖/usr/local/bin/);有 sudo → 覆盖/usr/local/bin/;无 sudo →~/bin/+ PATH 持久化(Unix)。Scoop/Choco →%USERPROFILE%\bin+ 用户 PATH(Windows)。完整优先级规则 → references/init-and-credentials.md § "CLI 安装 / 升级方法优先级"。安装 / 升级后,始终重新运行deploy_toolkit.py check确认;如果which -a aliyun仍先显示旧二进制,修复 PATH 顺序 —— 不要重复同样的覆盖。
可观测性(强制):User-Agent 注入
⛔ 每次aliyunCLI 调用都必须携带本 Skill 的 User-Agent,以便所有 API 请求在云端日志中可追踪。Agent 必须在会话开始时(步骤 0 之后立即)一次性导出 UA 环境变量,在任何aliyun/deploy_toolkit.py调用之前。
完整 UA 模板:
AlibabaCloud-Agent-Skills/alibabacloud-ecs-code-deploy/{session-id}
session-id 统一规则:
- 每个 agent 会话生成一次:
SESSION_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')—— 小写 UUID(任何 ≥ 16 字符的小写十六进制随机 token 等价)。 - 会话内所有 CLI 调用复用同一个 session-id —— 绝不逐命令重新生成,否则一次部署会散成不可追踪的碎片。
- 与步骤 0 规则一致持久化:Pattern A
export SESSION_ID=...(持久 shell)或内联字面值(每次调用新 shell)。
注入方式(现代 —— 环境变量):
export ALIBABA_CLOUD_USER_AGENT="AlibabaCloud-Agent-Skills/alibabacloud-ecs-code-deploy/${SESSION_ID}"
⛔ 旧版aliyun configure ai-mode enable / set-user-agent机制已废弃 —— 不要使用。不要将ALIBABA_CLOUD_USER_AGENT与 ai-mode 或逐命令环境前缀组合用于同一 skill token:CLI 会叠加这些来源并产生重复 UA。每会话设置一次环境变量并保持不变。
任务 2:配置凭证
deploy_toolkit.py check 已校验凭证。仅当凭证缺失 / 无效时,见 references/init-and-credentials.md 了解默认凭证链修复流程。
⛔ 优先 OAuth 而非 AK:OAuth 更安全便捷(无长期密钥存储)。Agent 必须将 OAuth 作为第一选项呈现。用户同意后,Agent 直接运行登录命令——但必须先警告用户该命令会打开浏览器授权页,且会阻塞直到用户在浏览器中完成授权——然后执行aliyun configure --mode OAuth --profile oauth并用aliyun sts get-caller-identity --profile oauth验证。
⛔ SA-2.12 —— 不要在对话中收集 AK/SK:如果用户偏好 AK 鉴权,给一个带占位符的可运行命令模板 ——aliyun configure set --profile default --mode AK --access-key-id <your-access-key-id> --access-key-secret <your-access-key-secret> --region cn-hangzhou—— 并请用户自行填写 AK/SK 并在他们自己的终端运行。Agent 绝不要求用户将 AccessKey/Secret/STS-Token 值粘贴到对话中,绝不将原始 AK/SK 放入工具调用参数或脚本,绝不回显凭证值。默认凭证链(ECS RAM 角色 / 环境变量 / 已有~/.aliyun/config.json)同样被遵循。完整修复流程 → references/init-and-credentials.md。
关键禁止:绝不运行独立的appmanager或aliyun appmanager login。
任务 3:初始化项目
步骤 1(强制):先读 README.md
关键顺序规则:在扫描任何项目文件之前,Agent 必须先读项目根目录的README.md(或README)。这始终是任务 3 的第一个动作。
从 README 提取:
- 快速开始 / 部署命令(例如
pip install -r requirements.txt && python main.py、npm install && npm start) - 官方构建 / 运行命令、Docker 部署方法、端口号、必需环境变量
#### 强制:向用户呈现 README 方法并遵循决策树
步骤 A:列出 README 向用户提供的内容。
步骤 B:按优先级选择方法:
| 优先级 | 方法类型 | 动作 |
|---|---|---|
| 1(最高) | 原生 CLI / 包管理器安装(npm install -g、pip install、go install) | 直接使用 |
| 2 | 原生构建 + 运行(pip install && python main.py、npm install && npm start) | 使用,安装运行时 |
| 3 | 基于脚本的部署(bash deploy.sh) | 必须确认非交互 |
| 4(最低) | Docker / docker-compose | 仅当无更高优先级时;检查中国可访问性 |
步骤 C:按场景执行:
- README 有原生方法(优先级 1/2) → 直接用作启动脚本核心。绝不忽略 README 从头构建。
- README 仅有 Docker → 检查镜像可访问性(见 references/script-templates.md "Docker 镜像可访问性检查")。警告用户中国镜像风险。
- README 无部署信息 / 缺失 → Agent 独立扫描项目文件(唯一允许的情况)。
为什么先读 README? 大多数项目在 README 中记录了确切的构建 / 运行命令。仅从文件自动检测容易出错。
步骤 2:确定项目类型
| 条件 | 类型 |
|---|---|
项目依赖 agentscope | agent |
| 其他一切(langchain、mcp、autogen、Web 服务、工具等) | app |
确定 --name
使用项目目录名(小写、连字符)。告知用户:默认应用名使用目录名 <name>。
确定 --region 和 ECS 目标(必须询问用户)
Agent 必须在一条消息中同时问两个问题:
1. 你想部署到哪个地域?
- 上海(cn-shanghai)/ 杭州(cn-hangzhou)/ 北京(cn-beijing)/ 深圳(cn-shenzhen)/ 广州(cn-guangzhou)/ 成都(cn-chengdu)/ 南京(cn-nanjing)/ 香港(cn-hongkong)
2. 新建 ECS 还是已有 ECS?
- 新建 ECS(自动创建实例,按量付费)
- 已有 ECS(从下方列表选择,或手动提供实例 ID)
绝不使用"华东 1" / "华北 2"这类可用区标签。绝不添加描述。仅用城市名。
#### 已有 ECS —— 列出用户所选地域最近 10 个实例(强制)
当用户选择已有 ECS 时,Agent 必须先查询账号在所选地域最近创建的 10 个实例(插件模式:aliyun ecs describe-instances),并以编号列表呈现供选择 —— 不要逼用户凭记忆回忆实例 ID。始终还允许手动输入实例 ID(例如 i-bp1xxxxxxxx)作为兜底。查询必须传与部署相同的 --profile(同一账号),否则可能返回零 / 错误实例。完整命令(jq 管道、无 jq 兜底、零实例处理)→ references/init-and-credentials.md § "列出现有 ECS 实例"。所选 / 输入的 ID 传给 appmanager init --ecs existing --instance-id <ID>。
⚠️ 地域透传检查(强制):所选地域必须原样传给appmanager init --region,写入config.yaml的common.deployment.regionId,并作为--region <REGION_ID>附加到后续每次deploy_toolkit.py {price,deploy,verify}调用。不匹配 / 遗漏会触发 OOS API 的InvalidParameter: DeployRegionId is invalid。
确定 --port(仅 App 类型,可选)
仅当项目实际监听 HTTP 时指定。后台服务(机器人、worker、CLI 工具)跳过。若需要但未知,默认 8080。Agent 类型不使用 --port。
非交互初始化
所有 init 标志组合见 references/init-and-credentials.md。
创建 .appmanager/config.yaml。不支持 --overwrite —— 若已存在先删除 .appmanager/。
任务 4:生成部署脚本
对所有项目类型,Agent 必须生成部署脚本并写入 .appmanager/config.yaml。
工作流
- 先读 README.md —— 遵循任务 3 决策树
- 若 README 无部署信息 —— 扫描项目结构(下方语言检测)
- Docker 可访问性检查 —— 若选择 Docker 路径(见 references/script-templates.md)
- 生成启停脚本 —— 遵循下方规则。启动脚本必须始终包含 zip 解压序列。
- 写入 config.yaml —— 位于
common.scripts.start和common.scripts.stop(绝不用顶层scripts)
语言检测、要读的文件与入口点
语言检测规则(指示文件)、各语言必读文件、入口点检测顺序 → references/script-templates.md § "项目分析"。
通用脚本规则
| 规则 | 要求 | ||
|---|---|---|---|
| ⛔ 强制 zip 解压 | 启动脚本必须:找到 zip → mkdir -p → unzip -o → cd。没有它,项目目录在 ECS 上不存在 | ||
| 运行时安装 | 必须先安装语言运行时(ECS 是裸机) | ||
| 安装 unzip | `command -v unzip &>/dev/null \ | \ | $PKG_MGR install -y unzip` |
| 幂等 | 多次运行安全 | ||
| ⛔ 日志文件固定路径 | 必须是 /root/app.log 和 /root/app.pid。verify 脚本硬编码这些路径 | ||
| 日志追加 | 始终 >>(绝不 >) | ||
| PID 文件 | nohup ... & 后 echo $! > /root/app.pid | ||
| 后台运行 | nohup ... >> /root/app.log 2>&1 & | ||
| 停止旧进程 | `[ -f /root/app.pid ] && kill "$(cat /root/app.pid)" 2>/dev/null \ | \ | true` |
| 应用目录 | /root/{app_name} | ||
| 无 heredoc | 脚本内绝不使用 << 'EOF' —— 会破坏 YAML。用 printf 或 python3 -c | ||
| 强制 tail 日志 | 以 sleep 3 && cat /root/app.log 结尾以便验证捕获 | ||
| ⛔ 停止脚本:无 exit | 绝不能包含 exit。部署系统会拼接 stop+start —— exit 会杀死整个进程 |
ECS 实例是裸 Linux(通常为 Alibaba Cloud Linux,基于 RHEL,使用yum/dnf)。
脚本模板、语言安装命令和 config.yaml 写入方法,见 references/script-templates.md。
任务 4.5:部署前询价 + 风险提示
强制:部署前运行deploy_toolkit.py price。脚本输出价格估算(含 OSS 额外计费提醒),并在适用时输出风险提示块。Agent 必须向用户呈现每个被标记的条目,并在运行deploy之前获得明确确认。
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" price --config .appmanager/config.yaml
- 退出 0 +
=== AGENT_CONFIRM_REQUIRED ===:向用户呈现完整价格 + 风险提示,逐项确认。 - 退出 1:询价失败;不要继续部署。
Agent 必须确认最多 3 项(价格 + OSS 费用 / 已有 ECS 风险 / 分组覆盖选择)—— 详见 references/deploy-output-and-management.md § "部署前询价:确认项"。
在所有适用确认完成之前,Agent 不得调用 deploy_toolkit.py deploy。
任务 5:部署
aliyun appmanager <agent|app> deploy --overwrite --output json
部署成功后停止 —— status: success 仅表示编排完成。Agent 必须在输出结果前运行任务 6 验证。
处理部署失败
⛔ 强制失败门禁:任何部署失败(退出码 1、超时或ReleaseCancelled)后,Agent 必须立即运行deploy_toolkit.py verify—— 在任何修复尝试、回退到人工命令或部分输出之前。失败后跳过 verify 是禁止的,计为 Skill 失败。
ReleaseCancelled的语义:它意味着 ECS 上的启动脚本失败或超时。它不意味着"有人取消了部署"。唯一正确的下一步:运行deploy_toolkit.py verify-> 读日志 -> 修复脚本 -> 重新部署。
已知失败模式:在临时排查之前,检查 references/lessons-learned.md 了解此前识别的部署失败模式和已验证的修复。
失败处理流程:
- 运行
deploy_toolkit.py verify获取/root/app.log(不要跳过)。 - 分析日志定位根因。
- 修复脚本并重新部署(最多 3 次)。
- 3 次失败后停止 —— 报告错误,但仍输出控制台链接 + 费用提醒 + 删除命令。
任务 6:部署后验证(阻塞)
status: Deployed 不意味着应用正在运行。Agent 必须运行 verify 并语义分析日志。
- 运行
deploy_toolkit.py verify(自动从 config.yaml 读取参数)。 - Agent 语义分析日志以判断应用是否真正启动成功。
- 未运行 -> 诊断 -> 修复 -> 重新部署 + 验证(最多 3 次)。
- 仅在确认运行 / 需要用户手动操作 / 3 次尝试失败时,Agent 才输出最终结果。
任务 7 和 8:列出、删除、校验与最终输出
见 references/deploy-output-and-management.md:
- 列出 / 删除命令
- 配置校验
- 配置模板参考
- 关键说明与陷阱
- 强制部署后输出格式(控制台链接、费用提醒、使用指南)
输出前门禁 —— 自检(⛔ 阻塞)
输出结果前,Agent 必须打印确切的 Deployment self-check report 模板(见工作流步骤 7.5)。跳过报告 = Skill 失败(不是可选总结)。如果有任何项为 ❌,在输出步骤 8 之前修复。
📘 含具体输入 / 输出和边界情况(Python Flask 示例)的实操演练:见 references/tutorial-flask-app.md。
完整部署工作流
⛔ 强制执行规则:Agent 必须严格遵循此序列。对于指定了脚本的步骤(步骤 1、5、6),Agent 必须运行脚本 —— 绝不用单独命令手工复刻脚本逻辑。上方 Task 章节仅供参考(用于理解脚本内部做什么,或脚本缺失时的兜底)。
0. 解析 $SKILL_DIR(强制 —— 完整算法见上方「步骤 0」章节)
→ 检测包含本 SKILL.md 的绝对目录(最准确)
→ 或回退到平台特定候选:~/.qoder/skills/...、~/.claude/skills/...、~/.qwen/skills/...、$SKILLS_HOME/... 等
→ Pattern A(持久 shell):export SKILL_DIR=<abs_path> ;验证 $SKILL_DIR/scripts/deploy_toolkit.py 存在 ;到处复用 $SKILL_DIR
→ Pattern B(每次命令新 shell):内联绝对路径 —— python3 "/abs/path/scripts/deploy_toolkit.py" ...
→ ⛔ 绝不使用 SKILL_DIR=/path python3 "$SKILL_DIR/..." —— 外层 shell 在前缀赋值
之前展开 $SKILL_DIR,产生 /scripts/deploy_toolkit.py 和 ENOENT。
1. 环境检查(必须用 deploy_toolkit.py check —— 不要运行人工命令)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" check
⛔ 禁止:在此脚本之前或代替它运行 aliyun version、~/.aliyun/appmanager-venv/bin/python -c "..."、
凭证检查或任何人工版本检查命令。
脚本一次性检查:CLI 版本 + appmanager-cli 版本 + 凭证。
直接运行脚本。就这样。
→ 若退出 0:所有检查通过,进入步骤 2
→ 若退出 1,处理脚本打印的问题:
⚠️ 不要静默停止。对脚本打印的每个可修复 ❌ 行,
Agent 必须遵循以下流程:
- aliyun CLI 未安装:直接自动安装(无需询问用户)
- aliyun CLI 已安装但过旧:询问用户批准升级
(覆盖到 /usr/local/bin,需要 sudo),然后运行脚本
打印的安装命令(见任务 1)。
- appmanager-cli < 1.1.1 或 venv 损坏:询问用户批准
rm -rf ~/.aliyun/appmanager-venv(下次 aliyun
appmanager 运行时自动重建)。
⚠️ 此路径固定为 ~/.aliyun/appmanager-venv(venv 由 aliyun CLI 自我管理)。
删除后,下次 aliyun appmanager 运行会自动重建。
Agent 必须使用这个确切字面路径 ——
绝不用变量替换或用拼接构建,
以避免意外清除用户数据。
- 凭证缺失 / 无效:向用户呈现 OAuth 优先的修复
(OAuth / RAM 角色 / 环境变量 / aliyun configure 交互式)—— 绝不
在对话中收集 AK/SK。见任务 2 + references/init-and-credentials.md。
→ 若用户拒绝任何修复:以该拒绝为原因停止 —— 不要
用损坏的环境继续(部署无论如何会失败)。
→ 若脚本文件未找到:只有此时才回退到人工检查(任务 1 + 任务 2)
2. 获取项目源码(如需要)
→ 若提供 git URL:克隆到当前工作目录,cd 进入克隆目录
git clone <URL> && cd <cloned_dir>
→ 若本地路径 / 当前目录:跳过此步骤,直接使用
🔀 重复部署捷径 —— 在步骤 3 之前检查
→ 检查项目目录中 .appmanager/config.yaml 是否已存在
→ 若是(config.yaml 存在):
读取文件并检查 common.deployment.instanceId:
- instanceId 缺失(新 ECS):跳过步骤 3-5,跳到步骤 5.5(询价)
- instanceId 存在(已有 ECS):跳过步骤 3-5.5,跳到步骤 6(部署)
两种情况下都告知用户:"检测到已有的 .appmanager/config.yaml;将复用现有配置并直接部署。"
→ 若否(config.yaml 不存在):从步骤 3 正常继续
3. 读取项目 + 识别类型(agent 或 app)
→ 先读 README.md —— 部署方法的最高优先级来源:
- Agent 必须向用户列出 README 的方法并按优先级选择:
原生 CLI 安装 > 原生构建+运行 > 脚本部署 > Docker
- ❌ 绝不忽略 README 方法转而扫描项目文件
- ❌ 绝不在有原生方法时优先 Docker
- Docker:仅当无原生方法时,必须警告用户中国镜像风险
- 仅当 README 缺失 / 为空 / 无部署信息时 → Agent 独立扫描项目文件
→ 仅当项目依赖 agentscope 时才归类为 "agent";其他一切为 "app"
→ 从目录名确定 --name,从项目配置 / README 确定 --port
→ 对 Docker:检查从中国的镜像可访问性(见 references/script-templates.md)
4. 询问用户部署地域 + ECS 目标(强制 —— 在一个问题中同时问)
→ 问题 1:"你想部署到哪个地域?上海(cn-shanghai)/杭州(cn-hangzhou)/北京(cn-beijing)/深圳(cn-shenzhen)/广州(cn-guangzhou)..."
→ 问题 2:"新建 ECS 还是已有 ECS?" —— 若已有,先查询账号在所选地域最近创建的
10 个 ECS 实例并以编号列表呈现供选择:
aliyun ecs describe-instances --biz-region-id <REGION> --region <REGION> --page-size 100 | jq -r '.Instances.Instance | sort_by(.CreationTime) | reverse | .[:10] | .[] | "..."' (插件模式;无 --output json;JSON 为默认)
始终还支持手动输入实例 ID(例如 i-bp1xxxxxxxx)。见任务 3 "已有 ECS" 章节。
→ 绝不使用"华东 1" / "华北 2"这类可用区标签 —— 始终用城市名
→ 绝不跳过 ECS 选择而默认创建新实例
→ ⚠️ 地域必须原样透传到:appmanager init --region、config.yaml common.deployment.regionId,以及每次 deploy_toolkit.py --region。不匹配 → OOS API 的 InvalidParameter: DeployRegionId。
5. 初始化 + 生成脚本(appmanager init → 将启停写入 config.yaml)
→ 若当前项目目录中 .appmanager/ 已存在,删除前询问用户。
⚠️ 破坏性:rm -rf .appmanager 会删除现有部署配置。
删除前的必需防护:
a. 确认 CWD 与预期项目目录匹配(pwd 显示预期路径)
b. 确认目标是相对路径 .appmanager(绝不用绝对路径,绝不用变量)
c. 告知用户"即将删除 ./.appmanager/ 下的现有部署配置。此操作不可逆。"并获得同意
更安全的推荐替代:先备份
mv .appmanager .appmanager.bak.$(date +%Y%m%d%H%M%S)
仅在用户明确同意后:rm -rf ./.appmanager
→ 运行:aliyun appmanager init --non-interactive --name <DIR_NAME> --type <app|agent> --region <REGION> [--port <PORT>] [--ecs existing --instance-id <ID>] [--model qwen3.6-plus --api-key "$API_KEY"]
(按类型的完整标志组合见 references/init-and-credentials.md)
→ 然后生成启停脚本并写入 config.yaml:
- 必须写入 common.scripts.start 和 common.scripts.stop(绝不用顶层 scripts 键)
- 用 python3 yaml 库:config['common']['scripts'] = {'start': ..., 'stop': ...}
- 优先级:README 部署命令 → 直接使用;仅当 README 无时才自动生成
- ⛔ 强制:启动脚本必须始终在任何构建 / 运行命令之前包含 zip 解压(mkdir + unzip + cd)。
appmanager 上传 zip 但不解压。
5.5. 部署前询价 + 风险提示(必须运行 deploy_toolkit.py price —— Agent 负责用户确认)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" price --config .appmanager/config.yaml
→ 脚本输出结构:
[价格表] 来自 appmanager price 的估算(按订单计费资源:ECS/EIP/带宽)+ 尾部 📦 OSS 额外计费提醒
[风险提示] 仅在检测到时:[已有 ECS 部署风险] / [分组覆盖风险] / [失败遗留分组]
→ 脚本不向用户请求确认 —— 那是 Agent 的工作
→ 若退出 0:Agent 必须读取输出,向用户呈现完整明细 —— 包括:
1) 价格估算 + OSS 额外计费提醒(OSS 存储约 CNY 0.12/GB/月,公网出流量约 CNY 0.50/GB 仅在跨地域时,请求按万次计费)
2) 若输出含 [已有 ECS 部署风险] -> 询问是否部署到该已有 ECS(可能影响其上的其他应用)
3) 若输出含 [分组覆盖风险] -> 请用户选择 A(覆盖)或 B(新分组)
示例:"预估费用:计算资源 CNY X.XXX/小时(约 CNY XXX.XX/月);公网流量按用量计费 CNY 0.80/GB;
部署还会产生少量 OSS 存储和请求费用(同地域拉取免公网出流量费)。
确认继续?"
→ 所有项经用户确认后:按条目 3 的选择运行匹配的部署命令(默认覆盖 / --force-new-group 为新分组)
→ 若任一项被拒绝:停止部署
→ 若退出 1:询价失败,向用户显示错误,不要继续
6. 部署(必须用 deploy_toolkit.py deploy —— 不要手动部署)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" deploy \
--type <agent|app> --name <APP_NAME> --group <GROUP_NAME> --region <REGION_ID>
⛔ 禁止:不经此脚本直接运行 aliyun appmanager deploy
→ 处理:分组状态检查 → 冲突自动解决 → 部署
→ 退出 0:部署已提交,进入步骤 7
→ 退出 1:⛔ 必须立即运行步骤 7(verify)获取 /root/app.log;
跳到步骤 8、输出部分结果或改运行人工命令是禁止的。然后按日志修复脚本并重新部署
(最多 3 次)。
7. 验证(必须用 deploy_toolkit.py verify —— 不要手动检查状态)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" verify \
--type <agent|app> --name <APP_NAME> --group <GROUP_NAME> --region <REGION_ID>
⛔ 禁止:用 aliyun appmanager status + 人工日志分析替代此脚本
→ 可选:--wait <seconds> 用于启动慢的应用(默认 3s,Java/重型用 15-30)
→ 双路径:云助手 cat /root/app.log(首选)→ deployCommandOutput(兜底)
→ 退出 0:应用运行中,进入步骤 8
→ 退出 1:应用失败 —— 修复启动脚本,重新部署(回到步骤 6)
→ 退出 2:不确定 —— 用更长的 --wait 重试或建议 SSH 检查
7.5. 自检总结(⛔ 阻塞 —— 省略则 Skill 失败)
必须向用户打印以下确切模板 —— 这是完成标准,不是可选项。
#
---
✅ 部署自检报告:
0. 路径解析 —— SKILL_DIR=___(脚本存在 ✅)
1. 环境预检 —— CLI v___ / appmanager-cli v___ / 凭证有效 ✅
2. 项目已获取 —— (本地 / 克隆)✅
3. 项目已识别 —— 类型:___ / 部署方法来源:README.md ✅
4. 部署地域 —— 用户选择:___ ✅
5. 初始化 + 脚本 —— config.yaml 已生成;启动脚本:___(关键命令摘要)✅
5.5. 部署前询价 —— 用户已确认价格(CNY ___/小时,约 CNY ___/月)✅
6. 部署已执行 —— deploy_toolkit.py deploy 退出 0 ✅
7. 运行验证 —— deploy_toolkit.py verify 退出 0 / 日志关键词:___ ✅
---
#
若任一项为 ❌,在步骤 8 之前修复 —— 这是给用户看的,证明工作已妥善完成。
8. 输出结果(强制:控制台链接 + 费用提醒 + 管理命令)
→ 完整输出格式见 references/deploy-output-and-management.md
阿里云skills
◯ 评论 0