本番環境のリリース経路は、すでにほぼ決まっている。コードは GitHub に置き、保護された workflow がリリースのタイミングを決め、Self-hosted Runner はレビュー済みの手順だけをサーバー上で実行する。PanelAlpha Engine の Show HN を見て気になったのは、AI がデプロイを手伝えるかどうかではなかった。アプリケーションのライフサイクルを MCP の制御プレーンに任せた場合、既存の Runner とどう役割を分けるのかを確かめたかった。

別の Ubuntu 24.04.2 VPS で PanelAlpha Engine v2.1.1 を試した。この記事の QA 時点では、このバージョンがプロジェクトの GitHub latest release だった。1 vCPU、1.9 GiB RAM、50 GB ディスクの環境では、2 時間を超えても Engine のインストール段階にとどまり、最後の記録は 70%。そこで後続の実験を打ち切った。

これは PanelAlpha をインストールできないという証明ではない。分かったのは、軽量な AI コマンド実行ツールではなく、Docker、ネットワーク、ファイアウォール、プロジェクト分離、バックアップ、監視まで踏み込む Hosting Control Plane だということだ。インストールが完了しなくても、Self-hosted Runner の代わりとして導入するべきか考え直すには十分な材料があった。

本番 Runner ではなく、まっさらな VPS から始めた

実験前の VPS に Docker はなく、docker version の終了コードは 127 だった。iptables と nft も利用できず、待ち受けポートはほぼ SSH と chrony のみ。この基準状態があるため、後で確認した Docker やファイアウォールの変化を、以前から残っていた設定と混同せずに済む。

PanelAlpha の インストール文書 も、新規の専用 Debian / Ubuntu VPS を想定している。インストーラーのソースには systemd-resolved、/etc/resolv.conf、Docker ネットワーク、ホストのファイアウォールを扱う処理がある。既存のブログ Runner や別の本番サーバーでは試さなかった。

実行前に bootstrap をファイルとして取得し、SHA-256 を計算した。curl | sh で直接流し込む方法は使っていない。

$ curl -fsSL https://get.panelalpha.com/engine -o panelalpha-installer.sh
$ sha256sum panelalpha-installer.sh
5d3c436269e09f8a813073691f61ad18329c0b87a818cb7fc3481344ac8e2496

テスト対象は v2.1.1 に固定した。

$ bash /root/panelalpha-installer.sh --engine-version v2.1.1 --no-tui

最初の試行はすぐに止まった。Git が未導入だったためインストーラーが追加しようとしたが、依存パッケージを取得できなかった。実際のログは次のとおりだ。

git : Depends: liberror-perl but it is not installable
E: Unable to correct problems, you have held broken packages.
[ERROR] Failed to install git (required to fetch the installer).

この試行の終了コードは 1。まだホスト側の依存関係を準備している段階なので、PanelAlpha 本体のインストール失敗とは分類していない。その後の検証では大規模なシステムパッケージ更新に入り、一度は終了コード 141 で終わった。さらに続けたところ、ようやく Engine のイメージ、ネットワーク、ファイアウォールの処理まで進んだ。

最初の予想を修正した点もある。ソースには systemd-resolved と resolv.conf を変更する経路があるものの、この VPS には最初から systemd-resolved.service がなく、resolver ファイルも外部 DNS を使っていた。そのため今回、DNS ファイルに実行前後の変化は観測していない。ソースにある機能と、この環境で実際に起きたことは別の証拠として扱う必要がある。

70% で止まっていても、ホストはすでに変わっていた

終了前にもう一度ホスト状態を採取した。Docker Engine は 29.8.2 が導入済みだったが、PanelAlpha の進捗ファイルはまだ次の状態だった。

step: Installing PanelAlpha engine
progress: 70

docker ps -a は空だった。「10 個のバックグラウンドコンテナーが動いている」と書く根拠はない。確認できたのは composer、DNS proxy、Exim、metrics、Pure-FTPd、SFTP を含む 6 個の PanelAlpha イメージだった。最大の composer イメージについて、Docker は disk usage を 795 MB と報告していた。

より目立ったのはネットワーク側の変化だ。初期状態には iptables / nft がなかったが、後の状態では UFW / Docker のルールと、PA-BUILD-EGRESS、PA-PUBLISHED、PA-TENANT-INPUT、PA-TENANT-NET などのチェーンが存在していた。一方、待ち受けポートは依然として SSH と chrony のみ。Engine が外部にサービスを提供する状態には達していなかった。

終了時の eth1 の累積 RX カウンターは 1,508,426,817 bytes だった。ただし、これを「PanelAlpha が 1.5 GB ダウンロードした」とは扱っていない。初期状態で RX カウンターを記録しておらず、システム更新、SSH、その他の通信を差し引けないからだ。確かなのは、数時間にわたる新規 VPS のインストール中に、アプリのデプロイが始まる前からネットワーク、イメージ、ホストのファイアウォールが大きく変わったことまでだ。

普段の GitHub Runner + Docker Compose とは感覚が違う。Runner は GitHub workflow に駆動される実行経路であり、PanelAlpha はアプリのホスティング制御プレーン全体を構築している。分離、ドメイン、データベース、ファイル、バックアップ、監視を扱うなら、より大きな基盤が必要なのは自然だ。

最終的に止めたのは、「PanelAlpha は駄目だ」という結論を出すためではない。さらに時間をかけてインストールを完了させても、最初の選定上の疑問には答えられなくなっていた。1C2G のこのマシンでは、制御プレーンのコールドスタートとホストの変更が、すでに考慮すべきコストだった。プロジェクトのデプロイ成功、失敗したリリースで旧バージョンを維持できるか、バックアップを復元できるかは未実施だ。公式説明を自分の実行結果の代わりにはしない。

modify 権限でも慎重さが必要な理由

MCP サーバーは稼働まで到達しなかったが、固定バージョンのソース監査は残してある。v2.1.1 の ToolPolicy は、3 つのモードに HTTP メソッドの上限を設けている。

モード許可されるメソッド
readonlyGET
modifyGET、POST、PUT、PATCH
fullGET、POST、PUT、PATCH、DELETE

一見すると modify は「変更できるが危険な削除はできない」ように見える。しかし、生成される MCP ツールまで読むと、それだけでは説明が足りない。

project_delete は DELETE なので modify の上限を通過しない。一方、backup_restore と project_push は両方 POST で、どちらにも IsDestructive マーカーがある。この verb ceiling の層だけなら、modify の範囲に入り得る。

これは認可なしで操作できる脆弱性を見つけたという意味ではない。Engine はツール登録前に toolset、denylist、TokenAbilities のスコープも適用し、バックアップ復元には confirm=true も要求する。実際の token を使った拒否テストは完了していないため、それらを迂回できるかどうかについて実行証拠はない。

設計上の注意はもっと単純だ。DELETE を禁止しても、重要な状態の上書きを防げるとは限らない。バックアップ復元、staging から live への反映、プロジェクト再構築は POST で行われる可能性がある。Coding Agent にインフラを扱わせるなら、まず readonly から始め、toolset と denylist を明示的に絞る。モード名だけを根拠にはしない。

バックアップと telemetry も、今回はソースと公式文書の確認にとどまった。Backups 文書 では、内蔵スケジューラーはなく外部 cron などが必要で、復元は現在のプロジェクト状態を上書きすると説明されている。Telemetry 文書は pae telemetry:disable と PANELALPHA_MONITORING= を空にする設定を区別する。前者は 6 時間ごとのヘルスチェックを停止し、後者はローカルのチェックを残して監視エンドポイントへの送信を止めるという説明だ。どちらも動的に実行していない。v2.1.1 の文書上の事実であり、この VPS で検証した挙動ではない。

今の Self-hosted Runner は置き換えない

既存の ChatGPT Web + GitHub + Self-hosted Runner の流れ と並べると、「どちらがどちらを置き換えるか」という問い自体が狭かったと感じる。

GitHub Self-hosted RunnerPanelAlpha Engine
主な役割GitHub workflow に制御された job の実行アプリとサーバーのホスティングライフサイクル管理
中心となる状態Git commit、workflow、releaseEngine 内のプロジェクトとホスティング状態
AI の接続方法Agent がコードや workflow を変更し GitHub が実行Agent が MCP / API から制御プレーンを操作
ホストへの介入workflow の処理内容によるインストール時から Docker、ネットワーク、ファイアウォールを構築
今回の証拠既存の本番経路を継続利用中インストール 70% と一部のホスト変化まで

ブログ、小規模サービス、少数の自己ホストプロジェクトには、GitHub + Self-hosted Runner + Docker Compose を維持する。Runner の方が安全、あるいは高性能だと証明したわけではない。今の source of truth、PR レビュー、リリース経路にすでに整合しており、新しい高権限制御プレーンが増やす状態や基盤のコストを、まだ相殺できないという判断だ。

逆に、数十のアプリでドメイン、データベース、ファイル、バックアップ、分離を統一管理し、制約されたインターフェースを通じて Coding Agent に操作させたいなら、PanelAlpha の位置付けには納得できる。見栄えのよい docker compose up ではなく、従来の hosting panel を Agent が呼び出せるインフラ API に変えようとしている。

今回、インストールで終了しても、この選定には十分だった。完全稼働後の使い勝手は分からないが、レビュー済みコードを数台のサーバーへ確実に公開するだけなら、AI 操作のために VPS 制御プレーン全体を追加する理由は今のところない。

次に試すなら、より余裕のある新規 VPS で、最初に readonly / modify / full の MCP 拒否マトリクスを完成させる。その後、失敗時のリリース、リモートバックアップの復元、telemetry の実挙動を調べる。長期的な AI 運用の入口として適切かを論じるのは、その結果が揃ってからだ。