alibabacloud-ecs-code-deploy について
ローカルディレクトリや Git URL のプロジェクトを `aliyun appmanager` で Alibaba Cloud ECS にデプロイするためのスキルです。環境確認、プロジェクト準備、デプロイ後のログ検証までの手順を定めています。
主な機能
- 01ローカルまたは Git のプロジェクトをデプロイ
- 02CLI、プラグイン、認証情報を確認
- 03プロジェクト README の実行手順を利用
- 04ログでデプロイを検証
活用シーン
- 01現在のディレクトリのプロジェクトを ECS にデプロイ
- 02Git URL から取得したプロジェクトをデプロイ
- 03ECS デプロイ後のログを確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ aliyun/ alibabacloud-aiops-skills --skill alibabacloud-ecs-code-deployインストール後、Claude Code で/alibabacloud-ecs-code-deployを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/deploy-output-and-management.mdinit-and-credentials.mdlessons-learned.mdram-policies.mdscript-templates.mdskill-dir-resolution.mdtutorial-flask-app.mdscripts/deploy_toolkit.pyrequirements.txt詳細
aliyun appmanager を使用して Alibaba Cloud ECS にデプロイする
概要
aliyun appmanager は、アプリケーション(App)や AI エージェントを Alibaba Cloud ECS にワンクリックでデプロイする、エージェント向けの CLI ツールです。非対話モード(--non-interactive)、構造化 JSON 出力(--output json)、ストリーミング NDJSON レスポンスをサポートしています。
デフォルトの動作:ユーザーがプロジェクトのパスや URL を指定せずに /alibabacloud-ecs-code-deploy を呼び出した場合、現在の作業ディレクトリにあるプロジェクトを Alibaba Cloud ECS にデプロイします。ユーザーが Git URL を指定した場合は、まず現在のディレクトリにクローンし、その後クローンしたディレクトリに cd してデプロイを進めます。
実行順序:エージェントは、正しい実行順序に従うため、このドキュメント末尾の「完全なデプロイワークフロー」セクションに必ず従ってください。以下のタスクセクションは参照用にトピック別に整理されています。番号は実行順序を示すものではありません。
必須:開始前に Todo リストを作成する
いずれかの手順を実行する前に、エージェントは以下のすべての項目を含む Todo リストを必ず作成してください。項目を省略しないでください。Todo リストを作成するまで、デプロイを開始しないでください。
Todo list (Deploy to Alibaba Cloud ECS):
[ ] 0. Resolve $SKILL_DIR (cross-platform path — MUST run first; see "Step 0" below)
[ ] 1. Environment pre-check (MUST run deploy_toolkit.py check; manual commands FORBIDDEN as replacement)
[ ] 2. Obtain project (clone git URL here if needed; skip for local projects)
── Check whether .appmanager/config.yaml already exists (repeat-deploy shortcut) ──
│ Exists + new ECS (no instanceId) → skip 3-5, start from 5.5 (price check)
│ Exists + existing ECS (has instanceId) → skip 3-5.5, jump to 6 (deploy)
│ Does not exist → proceed normally from 3
───────────────────────────────────────────────────────────────────────────────
[ ] 3. Read project (README.md -> quick-deploy method) + identify type (agent / app)
[ ] 4. Ask user for deployment config (region + new ECS / existing ECS)
[ ] 5. Init + generate scripts (appmanager init -> write start/stop scripts to config.yaml)
[ ] 5.5. Pre-deploy price check + risk warning (MUST run deploy_toolkit.py price; confirm price / OSS billing / existing-ECS impact / group overwrite item by item)
[ ] 6. Deploy (MUST run deploy_toolkit.py deploy; manual deploy command FORBIDDEN as replacement)
[ ] 7. Verify (MUST run deploy_toolkit.py verify; manual status command FORBIDDEN as replacement)
[ ] 8. Output final result (console link + cost reminder + management commands)
⛔ スクリプト優先ルール:手順 1、5、6、7 には、
$SKILL_DIR/scripts/deploy_toolkit.pyに専用のツールキットスクリプトがあります($SKILL_DIRは以下の 手順 0 で解決します。Qoder、Claude Code、その他のプラットフォームで動作します)。エージェントは、各手順で対応するサブコマンドを最初かつ唯一のアクションとして直接実行しなければなりません。スクリプトを実行する前や、スクリプトの代わりに、手動で 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 は必ず実施してください。ログの検証を省略して「デプロイに成功しました」と直接出力したエージェントは、このスキルを正しく完了したことになりません。
deploy_toolkit.py verifyの終了コードが 1(失敗)の場合、エージェントは問題を修正し、項目 7 に進む前に再デプロイしなければなりません。
手順 0(必須):$SKILL_DIR を解決する — クロスプラットフォームのパス
ツールキットスクリプトは
<skill-root>/scripts/deploy_toolkit.pyにあります。プラットフォームごとにスキルのインストール先は異なります(Qoder/Claude Code/Qwen など)。エージェントは、セッション開始時にスキルの絶対パスを一度だけ解決し、以下で$SKILL_DIRが登場するすべての箇所で再利用しなければなりません。プラットフォーム固有のパスをハードコードすることは禁止です。
10 個の候補を用いた検出アルゴリズム、export + test -f による確認スニペット、Pattern A/Pattern B/⛔ アンチパターンの使用ルールの詳細は、references/skill-dir-resolution.md を参照してください。
簡単なまとめ(詳細はリファレンスを参照してください):
- ✅ Pattern A(永続シェル):
export SKILL_DIR="/abs/path"を実行し、後からpython3 "$SKILL_DIR/scripts/deploy_toolkit.py" <sub>を実行する - ✅ Pattern B(呼び出しごとに新しいシェル):絶対パスをインラインで指定する —
python3 "/abs/path/scripts/deploy_toolkit.py" <sub> - ⛔ アンチパターン:
SKILL_DIR=/path python3 "$SKILL_DIR/..."— 外側のシェルが、プレフィックスによる代入の前に$SKILL_DIRを展開するため、/scripts/deploy_toolkit.pyとなり、ENOENT が発生します。python3: can't open file '/scripts/deploy_toolkit.py'が表示された場合は、Pattern A または B に切り替えてください。
タスク 1:Alibaba Cloud 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 で終了した場合、エージェントはワークフローを黙って停止してはいけません。次の手順に従ってください。
- CLI がインストールされていない → ユーザーに確認せず、そのまま自動インストールします。インストールコマンド(以下のスニペット、または適切なアーキテクチャに対応する references/init-and-credentials.md を参照)を実行し、その後
deploy_toolkit.py checkを再実行して確認します。- 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 Install/Upgrade Method Priority」を参照してください。インストール/アップグレード後は、必ずdeploy_toolkit.py checkを再実行して確認してください。which -a aliyunで古いバイナリが引き続き先に表示される場合は、PATH の順序を修正してください。同じ上書きを繰り返してはいけません。
可観測性(必須):User-Agent の挿入
⛔ すべての
aliyunCLI 呼び出しに、このスキルの User-Agent を付与する必要があります。これにより、すべての API リクエストをクラウド側のログで追跡できます。エージェントはセッション開始時(Step 0 の直後)に、aliyunまたはdeploy_toolkit.pyを呼び出す前に、UA 環境変数を一度だけエクスポートする必要があります。
UA の完全なテンプレート:
AlibabaCloud-Agent-Skills/alibabacloud-ecs-code-deploy/{session-id}
session-id の統一ルール:
- エージェントのセッションごとに一度だけ生成します:
SESSION_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')— 小文字の UUID を使用します(16 文字以上の小文字の 16 進数によるランダムなトークンでも同等です)。 - セッション内のすべての CLI 呼び出しで同じ session-id を再利用してください。コマンドごとに再生成してはいけません。そうすると、1 回のデプロイが追跡できない断片に分散してしまいます。
- Step 0 のルールに従って一貫して保持してください。パターン A は
export SESSION_ID=...(永続的なシェル)、または呼び出しごとに新しいシェルを使う場合は値を直接記述します。
挿入方法(最新 — 環境変数):
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 やコマンドごとの環境変数プレフィックスと組み合わせてはいけません。CLI がこれらの設定元を重ねて、UA が重複するためです。環境変数はセッションごとに一度だけ設定し、そのままにしてください。
タスク 2:認証情報を設定する
deploy_toolkit.py check では、すでに認証情報が検証されています。認証情報が不足または無効な場合に限り、デフォルト認証情報チェーンの修復フローについて references/init-and-credentials.md を参照してください。
⛔ AK より OAuth を優先してください:OAuth はより安全で便利です(長期的なシークレットの保存が不要です)。エージェントは、必ず OAuth を最初の選択肢として提示しなければなりません。ユーザーが同意したら、エージェントはログインコマンドを直接実行します。ただし、まずコマンドによってブラウザーの認証ページが開き、ユーザーがブラウザーで認証を完了するまで処理がブロックされることを警告してから、
aliyun configure --mode OAuth --profile oauthを実行し、aliyun sts get-caller-identity --profile oauthで検証しなければなりません。⛔ SA-2.12 — チャットで AK/SK を収集しないでください:ユーザーが AK 認証を希望する場合は、プレースホルダーを含む、すぐに実行できるコマンドテンプレートを1 つ提示してください。テンプレートは
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 を入力して、自身のターミナルで実行するよう依頼してください。エージェントは、AccessKey/Secret/STS-Token の値をチャットに貼り付けるようユーザーに求めてはなりません。ツール呼び出しの引数やスクリプトに生の AK/SK を含めたり、認証情報の値をそのまま表示したりしてもなりません。デフォルト認証情報チェーン(ECS RAM Role/環境変数/既存の~/.aliyun/config.json)も使用されます。修復フローの全容 → references/init-and-credentials.md。重大な禁止事項:単独の
appmanagerまたはaliyun appmanager loginを実行してはなりません。
タスク 3:プロジェクトを初期化する
ステップ 1(必須):最初に README.md を読む
重大な順序ルール:プロジェクト内のファイルをスキャンする前に、エージェントはプロジェクトルートの
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 にデプロイ情報がない/README が存在しない → エージェントが独自にプロジェクトファイルをスキャンします(これが許可される唯一のケースです)。
なぜ最初に README を読むのですか? ほとんどのプロジェクトでは、正確なビルド/実行コマンドが記載されています。ファイルだけから自動検出すると、エラーが起こりやすくなります。
ステップ 2:プロジェクトの種類を判定する
| 条件 | 種類 |
|---|---|
プロジェクトが agentscope に依存している | agent |
| それ以外すべて(langchain、mcp、autogen、Web サービス、ツールなど) | app |
--name を決定する
プロジェクトディレクトリ名を使用します(小文字、ハイフン区切り)。ユーザーに Default app name uses the directory name <name> と伝えてください。
--region と ECS ターゲットを決定する(ユーザーへの確認が必須)
エージェントは、次の2つの質問を1つのメッセージで同時に行う必要があります:
1. どのリージョンにデプロイしますか?
- 上海(cn-shanghai)/杭州(cn-hangzhou)/北京(cn-beijing)/深圳(cn-shenzhen)/広州(cn-guangzhou)/成都(cn-chengdu)/南京(cn-nanjing)/香港(cn-hongkong)
2. 新しい ECS と既存の ECS のどちらを使用しますか?
- 新しい ECS(インスタンスを自動作成、従量課金)
- 既存の ECS(以下のリストから選択するか、インスタンス ID を手動で指定)
「East China 1」/「North China 2」のようなゾーンベースのラベルは絶対に使用しないでください。説明を追加しないでください。都市名のみを使用します。
既存の ECS — 選択したリージョンにある、ユーザーの最新10件のインスタンスを一覧表示する(必須)
ユーザーが既存の ECSを選択した場合、エージェントはまず、選択したリージョンにある、アカウントで作成日時が新しい10件のインスタンスを照会(プラグインモード:aliyun ecs describe-instances)し、選択用の番号付きリストとして提示する必要があります。ユーザーにインスタンス ID を思い出させないでください。代替手段として、インスタンス ID の手動入力(例:i-bp1xxxxxxxx)も必ず許可してください。照会にはデプロイ時と同じ --profile(同じアカウント)を渡す必要があります。渡さない場合、インスタンスが0件返されたり、誤ったインスタンスが返されたりする可能性があります。完全なコマンド(jq パイプライン、jq がない場合のフォールバック、インスタンスが0件の場合の処理)→ references/init-and-credentials.md §「既存の ECS インスタンスの一覧表示」。選択または入力された ID は、appmanager init --ecs existing --instance-id <ID> に渡します。
⚠️ リージョン伝播チェック(必須):選択したリージョンは、そのまま
appmanager init --regionに渡し、config.yamlのcommon.deployment.regionIdに書き込み、その後のすべてのdeploy_toolkit.py {price,deploy,verify}呼び出しに--region <REGION_ID>として指定する必要があります。不一致または指定漏れがあると、OOS API からInvalidParameter: DeployRegionId is invalidが返されます。
--port を決定する(App タイプのみ、任意)
プロジェクトが実際に HTTP でリッスンする場合にのみ指定します。バックグラウンドサービス(ボット、ワーカー、CLI ツール)では省略してください。必要なのに値が不明な場合は、デフォルトで 8080 を使用します。Agent タイプでは --port を使用しません。
非対話型の初期化
すべての init フラグの組み合わせについては、references/init-and-credentials.md を参照してください。
.appmanager/config.yaml を作成します。--overwrite はサポートされていません。既存の .appmanager/ がある場合は、先に削除してください。
タスク 4:デプロイスクリプトを生成する
すべてのプロジェクトタイプで、エージェントはデプロイスクリプトを生成し、.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 を使用してください。スクリプトにこれらのパスがハードコードされていることを確認してください |
| ログへの追記 | 常に >> を使用してください(> は使用しないでください) |
| 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} |
| ヒアドキュメント禁止 | スクリプト内では << 'EOF' を絶対に使用しないでください。YAML が壊れます。printf または python3 -c を使用してください |
| ログ末尾の出力は必須 | 確認用のログを取得できるよう、最後に sleep 3 && cat /root/app.log を実行してください |
⛔ 停止スクリプト:exit 禁止 | exit を含めてはいけません。デプロイシステムは停止スクリプトと開始スクリプトを連結するため、exit を使うとプロセス全体が終了します |
ECS インスタンスは最小構成の Linux です(通常は Alibaba Cloud Linux。RHEL ベースで、
yum/dnfを使用します)。
スクリプトテンプレート、言語のインストールコマンド、config.yaml の記述方法については、references/script-templates.md を参照してください。
タスク 4.5:デプロイ前の料金確認とリスク警告
必須:デプロイ前に
deploy_toolkit.py priceを実行してください。このスクリプトは料金見積もり(OSS の追加料金に関する注意を含む)と、該当する場合はリスク警告のブロックを出力します。エージェントは、警告対象となった項目をすべてユーザーに提示し、deployを実行する前に明示的な確認を得る必要があります。
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" price --config .appmanager/config.yaml
- 終了コード 0 と
=== AGENT_CONFIRM_REQUIRED ===:料金とリスク警告の全内容をユーザーに提示し、各項目について確認してください。 - 終了コード 1:料金の問い合わせに失敗しました。デプロイに進まないでください。
エージェントは最大 3 項目(料金と OSS 料金/既存 ECS のリスク/グループの上書き方法)について確認する必要があります。詳しくは references/deploy-output-and-management.md の「デプロイ前の料金確認:確認項目」を参照してください。
該当するすべての確認が完了するまで、エージェントは
deploy_toolkit.py deployを実行してはいけません。
タスク 5:デプロイ
aliyun appmanager <agent|app> deploy --overwrite --output json
デプロイ成功後は停止してください —
status: successが示すのはオーケストレーションの完了のみです。結果を出力する前に、エージェントはタスク 6 の検証を実行する必要があります。
デプロイ失敗への対応
⛔ 必須の失敗時ゲート:デプロイが失敗した場合(終了コード 1、タイムアウト、または
ReleaseCancelled)、エージェントは修正を試みる前、手動コマンドへの切り替え前、または一部のみを出力する前に、直ちにdeploy_toolkit.py verifyを実行する必要があります。失敗後に検証を省略することは禁止されており、スキルの失敗とみなされます。
ReleaseCancelledの意味:ECS 上の開始スクリプトが失敗したか、タイムアウトしたことを意味します。「誰かがデプロイをキャンセルした」という意味ではありません。次に行うべき正しい手順は、deploy_toolkit.py verifyを実行する → ログを読む → スクリプトを修正する → 再デプロイする、です。
既知の失敗パターン:場当たり的なトラブルシューティングを行う前に、特定済みのデプロイ失敗パターンと実証済みの修正方法を確認するため、references/lessons-learned.md を参照してください。
失敗時の対応フロー:
deploy_toolkit.py verifyを実行して/root/app.logを取得します(省略しないでください)。- ログを分析して根本原因を特定します。
- スクリプトを修正して再デプロイします(最大 3 回まで)。
- 3 回失敗したら停止してください。エラーを報告したうえで、コンソールリンク、料金に関する注意、削除コマンドも出力してください。
タスク 6:デプロイ後の検証(必須)
status: Deployedだからといって、アプリケーションが実行中とは限りません。エージェントは verify を実行し、ログを意味的に分析する必要があります。
deploy_toolkit.py verifyを実行します(パラメーターはconfig.yamlから自動的に読み込まれます)。- エージェントがログを意味的に分析し、アプリケーションが実際に正常起動したかどうかを判断します。
- 実行されていない場合は、診断して修正し、再デプロイして検証します(最大 3 回まで)。
- 実行中であることが確認された場合、ユーザーによる手動操作が必要な場合、または 3 回試行して失敗した場合にのみ、エージェントは最終結果を出力します。
タスク 7 と 8:一覧表示、削除、検証、最終出力
以下を参照してください:references/deploy-output-and-management.md。
- 一覧表示/削除コマンド
- 設定の検証
- 設定テンプレートのリファレンス
- 重要な注意事項と落とし穴
- デプロイ後に必ず出力する形式(コンソールリンク、コストに関する注意、使用ガイド)
出力前ゲート — セルフチェック(⛔ 必須)
結果を出力する前に、エージェントは Deployment self-check report テンプレート(ワークフローのステップ 7.5 を参照)をそのまま出力する必要があります。レポートを省略するとスキルの失敗になります(任意の概要ではありません)。項目に ❌ がある場合は、ステップ 8 を出力する前に修正してください。
📘 具体的な入出力とエッジケースを含む実践チュートリアル(Python Flask の例):references/tutorial-flask-app.md を参照してください。
デプロイワークフロー全体
⛔ 実行必須ルール:エージェントはこの手順に厳密に従う必要があります。スクリプトが指定されているステップ(ステップ 1、5、6)では、エージェントはスクリプトを実行する必要があります。個別のコマンドを使ってスクリプトの処理を手作業で再現してはいけません。上記のタスクセクションは参照用のみです(スクリプト内部の処理を理解する場合や、スクリプトが見つからない場合の代替手段として使用します)。
# 0. Resolve $SKILL_DIR (MANDATORY — see "Step 0" section above for full algorithm)
# → Detect the absolute directory containing THIS SKILL.md (most accurate)
# → Or fall back to platform-specific candidates: ~/.qoder/skills/..., ~/.claude/skills/..., ~/.qwen/skills/..., $SKILLS_HOME/..., etc.
# → Pattern A (persistent shell): export SKILL_DIR=<abs_path> ; verify $SKILL_DIR/scripts/deploy_toolkit.py exists ; reuse $SKILL_DIR everywhere
# → Pattern B (fresh shell per command): inline the absolute path — `python3 "/abs/path/scripts/deploy_toolkit.py" ...`
# → ⛔ NEVER use `SKILL_DIR=/path python3 "$SKILL_DIR/..."` — outer shell expands $SKILL_DIR
# BEFORE the prefix assignment, producing `/scripts/deploy_toolkit.py` and ENOENT.
# 1. Environment check (MUST use deploy_toolkit.py check — DO NOT run manual commands)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" check
# ⛔ FORBIDDEN: running `aliyun version`, `~/.aliyun/appmanager-venv/bin/python -c "..."`,
# credential checks, or ANY manual version-check commands before or instead of this script.
# The script checks ALL of: CLI version + appmanager-cli version + credentials in one run.
# Just run the script. Period.
# → If exit 0: all checks passed, proceed to step 2
# → If exit 1, address the issue printed by the script:
# ⚠️ DO NOT stop silently. For every fixable ❌ line the script prints,
# Agent MUST follow the flow below:
# - aliyun CLI NOT installed: AUTO-INSTALL directly (no need to ask user)
# - aliyun CLI already installed but outdated: ASK user to approve upgrade
# (covers to /usr/local/bin, needs sudo), then run the install command
# printed by the script (see Task 1).
# - appmanager-cli < 1.1.1 or BROKEN venv: ASK user to approve
# `rm -rf ~/.aliyun/appmanager-venv` (auto-recreates on next aliyun
# appmanager run).
# ⚠️ This path is fixed at ~/.aliyun/appmanager-venv (the venv is self-managed
# by the aliyun CLI). After deletion, the next `aliyun appmanager` run
# auto-recreates it. The Agent MUST use this exact literal path —
# NEVER replace it with a variable or build it via concatenation,
# to avoid accidentally wiping user data.
# - credentials missing/invalid: present OAuth-first remediation
# to the user (OAuth / RAM Role / env vars / `aliyun configure` interactive) — NEVER
# collect AK/SK in chat. See Task 2 + references/init-and-credentials.md.
# → If user refuses any fix: stop with that refusal as the reason — DO NOT
# continue with a broken environment (deployment will fail anyway).
# → If script file not found: ONLY THEN fall back to manual checks (Task 1 + Task 2)
# 2. Obtain project source (if needed)
# → If git URL provided: clone to CURRENT WORKING DIRECTORY, cd into cloned dir
# git clone <URL> && cd <cloned_dir>
# → If local path / current directory: skip this step, use directly
# 🔀 REPEAT DEPLOYMENT SHORTCUT — check BEFORE step 3
# → Check if .appmanager/config.yaml already exists in the project directory
# → If YES (config.yaml exists):
# Read the file and check for common.deployment.instanceId:
# - instanceId ABSENT (new ECS): skip steps 3-5, jump to step 5.5 (price check)
# - instanceId PRESENT (existing ECS): skip steps 3-5.5, jump to step 6 (deploy)
# In both cases, inform user: "Existing .appmanager/config.yaml detected; will reuse the existing config and deploy directly."
# → If NO (config.yaml does NOT exist): proceed normally from step 3
# 3. Read project + identify type (agent or app)
# → READ README.md FIRST — highest priority source for deployment method:
# - Agent MUST list README's methods to user and select by priority:
# Native CLI install > Native build+run > Script deploy > Docker
# - ❌ NEVER ignore README methods and scan project files instead
# - ❌ NEVER prefer Docker when native methods are available
# - Docker: ONLY when no native method exists, MUST warn user about China mirror risks
# - Only if README absent/empty/no deploy info → Agent scans project files independently
# → Only classify as "agent" if project depends on `agentscope`; everything else is "app"
# → Determine --name from directory name, --port from project config/README
# → For Docker: check image accessibility from China (see references/script-templates.md)
# 4. Ask user for deployment region + ECS target (MANDATORY — ask together in one question)
# → Question 1: "Which region do you want to deploy to? Shanghai(cn-shanghai)/Hangzhou(cn-hangzhou)/Beijing(cn-beijing)/Shenzhen(cn-shenzhen)/Guangzhou(cn-guangzhou)..."
# → Question 2: "New ECS or existing ECS?" — if existing, FIRST query the account's 10 most-recently-created
# ECS instances in the chosen region and present them as a numbered list for selection:
# aliyun ecs describe-instances --biz-region-id <REGION> --region <REGION> --page-size 100 | jq -r '.Instances.Instance | sort_by(.CreationTime) | reverse | .[:10] | .[] | "..."' (plugin mode; no `--output json`; JSON is the default)
# Also always support manual instance ID entry (e.g. i-bp1xxxxxxxx). See Task 3 "Existing ECS" section.
# → NEVER use zone-based labels like "East China 1" / "North China 2" — always use city names
# → NEVER skip the ECS choice and default to creating new
# → ⚠️ Region MUST be propagated verbatim to: appmanager init --region, config.yaml common.deployment.regionId, AND every deploy_toolkit.py --region. Mismatch → InvalidParameter: DeployRegionId from OOS API.
# 5. Init + generate scripts (appmanager init → write start/stop to config.yaml)
# → If .appmanager/ already exists in the CURRENT project directory, ask user before removing.
# ⚠️ DESTRUCTIVE: `rm -rf .appmanager` deletes the existing deployment config.
# Required guard before deletion:
# a. Confirm CWD matches the intended project directory (`pwd` shows expected path)
# b. Confirm target is the relative path `.appmanager` (NEVER absolute, NEVER with variables)
# c. Inform the user "About to delete the existing deployment config under ./.appmanager/. This is irreversible." and obtain consent
# Recommended safer alternative: back up first
# mv .appmanager .appmanager.bak.$(date +%Y%m%d%H%M%S)
# Only after explicit user consent: rm -rf ./.appmanager
# → Run: 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"]
# (See references/init-and-credentials.md for full flag combinations by type)
# → Then generate start/stop scripts and write to config.yaml:
# - MUST write to common.scripts.start and common.scripts.stop (NEVER top-level scripts key)
# - Use python3 yaml library: config['common']['scripts'] = {'start': ..., 'stop': ...}
# - PRIORITY: README deployment commands → use directly; only auto-generate when README has none
# - ⛔ MANDATORY: Start script MUST ALWAYS include zip extraction (mkdir + unzip + cd) BEFORE
# any build/run commands. appmanager uploads zip but does NOT extract it.
# 5.5. Pre-deploy price check + risk warning (MUST run deploy_toolkit.py price — Agent handles user confirmation)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" price --config .appmanager/config.yaml
# → Script output structure:
# [Price table] estimate from `appmanager price` (order-billed resources: ECS/EIP/bandwidth) + the trailing 📦 OSS extra-billing reminder
# [Risk warning] only when detected: [Existing-ECS deployment risk] / [Group overwrite risk] / [Failure-leftover group]
# → Script does NOT ask user for confirmation — that's the Agent's job
# → If exit 0: Agent MUST read the output, present the COMPLETE breakdown to user — including:
# 1) Price estimate + OSS extra-billing reminder (OSS storage ~CNY 0.12/GB/month, public outbound ~CNY 0.50/GB only when cross-region, requests billed per 10k)
# 2) If output contains [Existing-ECS deployment risk] -> ask whether to deploy onto that existing ECS (may impact other apps on it)
# 3) If output contains [Group overwrite risk] -> ask user to choose A (overwrite) or B (new group)
# Example: "Estimated cost: compute resources CNY X.XXX/hour (~CNY XXX.XX/month); public traffic billed by usage at CNY 0.80/GB;
# the deployment also incurs minor OSS storage and request fees (intra-region pull is free of public outbound charges).
# Confirm to continue?"
# → After ALL items confirmed by user: run the matching deploy command per item 3's choice (default overwrite / --force-new-group for new group)
# → If ANY item refused: STOP deployment
# → If exit 1: price query failed, show error to user, do NOT proceed
# 6. Deploy (MUST use deploy_toolkit.py deploy — DO NOT run deploy manually)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" deploy \
--type <agent|app> --name <APP_NAME> --group <GROUP_NAME> --region <REGION_ID>
# ⛔ FORBIDDEN: running `aliyun appmanager deploy` directly without this script
# → Handles: group status check → conflict auto-resolve → deploy
# → Exit 0: deploy submitted, proceed to step 7
# → Exit 1: ⛔ MUST run step 7 (verify) IMMEDIATELY to fetch /root/app.log;
# skipping to step 8, outputting partial results, or running manual
# commands instead is FORBIDDEN. Then fix script per log and redeploy
# (max 3 attempts).
# 7. Verify (MUST use deploy_toolkit.py verify — DO NOT check status manually)
python3 "$SKILL_DIR/scripts/deploy_toolkit.py" verify \
--type <agent|app> --name <APP_NAME> --group <GROUP_NAME> --region <REGION_ID>
# ⛔ FORBIDDEN: running `aliyun appmanager status` + manual log analysis instead of this script
# → Optional: --wait <seconds> for slow-starting apps (default 3s, Java/heavy use 15-30)
# → Dual-path: Cloud Assistant cat /root/app.log (preferred) → deployCommandOutput (fallback)
# → Exit 0: app running, proceed to step 8
# → Exit 1: app failed — fix start script, re-deploy (back to step 6)
# → Exit 2: inconclusive — retry with longer --wait or suggest SSH check
# 7.5. Self-check summary (⛔ BLOCKING — skill fails if omitted)
# MUST print the exact template below to the user — this is a completion criterion, NOT optional.
#
# ---
# ✅ Deployment self-check report:
# 0. Path resolution — SKILL_DIR=___ (script exists ✅)
# 1. Environment pre-check — CLI v___ / appmanager-cli v___ / credentials valid ✅
# 2. Project obtained — (local / cloned) ✅
# 3. Project identified — type: ___ / deploy method source: README.md ✅
# 4. Deployment region — user choice: ___ ✅
# 5. Init + scripts — config.yaml generated; start script: ___ (key command summary) ✅
# 5.5. Pre-deploy price check — user confirmed price (CNY ___/hour, ~CNY ___/month) ✅
# 6. Deploy executed — deploy_toolkit.py deploy exit 0 ✅
# 7. Run verification — deploy_toolkit.py verify exit 0 / log keywords: ___ ✅
# ---
#
# If any item is ❌, fix it BEFORE step 8 — this is for the USER to see, proving the work is properly done.
# 8. Output results (MANDATORY: console link + cost reminder + management commands)
# → See references/deploy-output-and-management.md for full output format