# PanelAlpha Engine 實測：AI 管理 VPS，能取代 GitHub Self-hosted Runner 嗎？

> Canonical: https://vxi.me/zh-tw/posts/panelalpha-engine-vps-hosting-control-plane/
> Locale: zh-tw
> Published: 2026-10-08
> Updated: 2026-10-08
> Markdown: https://vxi.me/zh-tw/posts/panelalpha-engine-vps-hosting-control-plane.md

我現在的正式環境發佈流程已經比較固定：程式碼進 GitHub，受保護的 workflow 決定何時發佈，Self-hosted Runner 只負責在伺服器上執行已經審查過的步驟。前陣子看到 [PanelAlpha Engine 的 Show HN](https://news.ycombinator.com/item?id=49991829)，我最想確認的不是「AI 能不能幫我部署」，而是另一個更實際的問題：如果把應用程式生命週期交給 MCP 控制平面，它和現有 Runner 到底是什麼關係？

我用一台獨立的 Ubuntu 24.04.2 測試 VPS 跑了 PanelAlpha Engine v2.1.1。這個版本截至本次 QA 仍是專案的 [GitHub latest release](https://github.com/panelalpha/panelalpha-engine/releases/tag/v2.1.1)。結果沒有得到漂亮的「一鍵部署成功」：在 1 vCPU、1.9 GiB RAM、50 GB 磁碟的機器上，安裝超過兩小時仍停在 Engine 安裝階段，最後記錄的進度是 70%，我主動停止了後續實驗。

這不代表 PanelAlpha 裝不起來。它真正給我的資訊是：這不是輕量的 AI 指令執行器，而是一套會進入 Docker、網路、防火牆、專案隔離、備份和監控邊界的 Hosting Control Plane。安裝沒跑完，反而足夠讓我重新判斷它是否應該取代現有的 Self-hosted Runner。

## 我沒有裝到正式環境，先看乾淨 VPS 會發生什麼

這次從乾淨 VPS 開始。實驗前沒有 Docker，`docker version` 回傳 127；系統也沒有可用的 `iptables` 和 `nft` 指令，監聽連接埠基本上只有 SSH 與 chrony。這個基準狀態很重要，因為後面觀察到的 Docker 和防火牆變化，至少能明確歸因於安裝過程，而不是機器原本留下的設定。

PanelAlpha 自己的 [安裝文件](https://github.com/panelalpha/panelalpha-engine/blob/1e19bbf22a49c638f9e886fde653e02bbdc4bea5/docs/02-getting-started/install.md) 也寫得很清楚：更適合新的、專用的 Debian / Ubuntu VPS。原始碼中的安裝程式還包含 `systemd-resolved`、`/etc/resolv.conf`、Docker 網路和主機防火牆處理邏輯。所以我沒有拿既有的部落格 Runner 或其他正式環境機器做實驗。

實際執行前，我先將 bootstrap 下載為檔案並計算 SHA-256，而不是直接 `curl | sh`：

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

測試版本隨後固定為 v2.1.1：

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

第一輪沒有走遠。安裝程式發現系統缺少 Git，嘗試安裝時遇到依賴套件不可用，實際記錄如下：

```text
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`，而且 `resolv.conf` 原本使用外部 DNS，所以本次執行前後，DNS 檔案沒有可觀察的變化。原始碼能力和這一次機器上真正發生的事，應該分開說明。

## 安裝停在 70%，主機卻已經不是原本的狀態

實驗結束前，我再次擷取機器狀態。Docker Engine 已經安裝完成，版本是 29.8.2；PanelAlpha 進度檔案仍顯示：

```text
step: Installing PanelAlpha engine
progress: 70
```

`docker ps -a` 仍為空。這次實驗不是「10 個背景容器已經執行」。能直接確認的是，機器上出現了 6 個 PanelAlpha 映像，包括 composer、DNS proxy、Exim、metrics、Pure-FTPd 和 SFTP。最大的 composer 映像由 Docker 回報為 795 MB disk usage。

更明顯的變化發生在網路層。基準狀態中 `iptables` / `nft` 工具不存在；安裝推進後，主機有了 UFW / Docker 規則，並出現 `PA-BUILD-EGRESS`、`PA-PUBLISHED`、`PA-TENANT-INPUT`、`PA-TENANT-NET` 等 PanelAlpha 鏈。同時，監聽連接埠快照仍只有 SSH 和 chrony，Engine 本身尚未準備好對外提供服務。

結束時，`eth1` 的累計 RX 計數是 1,508,426,817 bytes。這個數字我不會直接寫成「PanelAlpha 下載了 1.5 GB」，因為基準檔案沒有記錄介面 RX 計數，沒法扣除系統升級、SSH 和其他流量。能確認的是：在持續數小時的乾淨 VPS 安裝期間，網路、Docker 映像和主機防火牆都發生明顯變化，而應用程式部署尚未開始。

這和我平常使用 GitHub Runner + Docker Compose 的感受很不一樣。Runner 比較像受 GitHub workflow 驅動的執行通道；PanelAlpha 則在建立整套應用程式託管控制平面。後者需要更多基礎設施並不奇怪，因為它還要處理專案隔離、網域、資料庫、檔案、備份和監控等生命週期。

所以我最後停止測試，不是為了下「PanelAlpha 不行」的結論，而是繼續耗時間把它硬裝完，已經不足以回答最初的選型問題。對這台 1C2G 機器而言，控制平面的冷啟動與主機改動本身，已是必須納入的成本。專案是否能部署成功、失敗的發佈是否保留舊版本、備份是否能還原，我這次都沒有測到，官方說明也不等於自己的執行結果。

## `modify` 權限為什麼仍需謹慎

雖然沒跑到 MCP 伺服器，我仍保留了先前固定版本的原始碼稽核。PanelAlpha v2.1.1 的 [ToolPolicy](https://github.com/panelalpha/panelalpha-engine/blob/1e19bbf22a49c638f9e886fde653e02bbdc4bea5/core/app/Mcp/ToolPolicy.php) 依 HTTP 方法，為三種權限模式設定上限：

| 權限模式 | 允許的方法 |
| --- | --- |
| `readonly` | GET |
| `modify` | GET、POST、PUT、PATCH |
| `full` | GET、POST、PUT、PATCH、DELETE |

乍看之下，`modify` 很像「能修改，但不准危險刪除」。繼續看產生的 MCP 工具，就會發現這個理解不夠完整。

`project_delete` 是 DELETE，所以不會通過 `modify` 的方法上限；但 [`backup_restore`](https://github.com/panelalpha/panelalpha-engine/blob/1e19bbf22a49c638f9e886fde653e02bbdc4bea5/core/app/Mcp/Tools/Api/Backups/BackupRestoreTool.php) 和 [`project_push`](https://github.com/panelalpha/panelalpha-engine/blob/1e19bbf22a49c638f9e886fde653e02bbdc4bea5/core/app/Mcp/Tools/Api/Projects/ProjectPushTool.php) 都是 POST，也都帶有 `IsDestructive` 標記。只看這層 verb ceiling，它們可以落在 `modify` 範圍內。

這不是「未授權漏洞」的結論。Engine 在註冊工具前，還會套用 toolset、denylist 和 TokenAbilities 的 token 範圍；備份還原請求也要求 `confirm=true`。我沒有完成真實 token 的動態拒絕測試，所以並沒有執行證據可以判斷這些保護是否能被繞過。

它給我的工程提醒更簡單：替 Coding Agent 設計基礎設施權限時，不允許 DELETE，不等於不會覆寫重要狀態。還原備份、將 staging 推到 live、重建專案，都可能經由 POST 完成。若真要接入 Agent，我會從 `readonly` 開始，再明確縮小 toolset 和 denylist，而不只看三個模式名稱。

備份與 telemetry 這次也停留在原始碼與官方文件的範圍。[Backups 文件](https://github.com/panelalpha/panelalpha-engine/blob/1e19bbf22a49c638f9e886fde653e02bbdc4bea5/docs/05-capabilities/backups.md) 明確表示沒有內建排程，需要外部 cron 等工具；還原會覆寫目前的專案狀態。Telemetry 文件則區分 `pae telemetry:disable` 和將 `PANELALPHA_MONITORING=` 留空：前者停掉每六小時的健康檢查，後者的官方描述是保留本機檢查，但不向監控端點傳送報告。這些行為我未曾動態執行，只能當作 v2.1.1 的文件事實。

## 我現在仍保留 Self-hosted Runner

把這輪實驗與既有的 [ChatGPT Web + GitHub + Self-hosted Runner 工作流程](/zh-tw/posts/chatgpt-web-github-self-hosted-runner/) 放在一起看，我反而覺得「誰取代誰」這個問題太窄。

| | GitHub Self-hosted Runner | PanelAlpha Engine |
| --- | --- | --- |
| 主要職責 | 執行受 GitHub workflow 控制的 job | 管理應用程式與伺服器託管生命週期 |
| 核心狀態 | Git commit、workflow、release | Engine 內的專案與託管狀態 |
| AI 接入方式 | Agent 改程式碼或 workflow，再由 GitHub 執行 | Agent 經 MCP / API 直接操作控制平面 |
| 主機介入 | 取決於 workflow 本身做什麼 | 安裝時就建立 Docker、網路與防火牆基礎 |
| 本次驗證範圍 | 既有正式環境流程持續使用 | 僅安裝到 70% 與部分主機變化 |

對我的部落格、小型服務和少數自行託管專案而言，目前仍選擇 GitHub + Self-hosted Runner + Docker Compose。並不是因為我證明 Runner 更安全或效能更好，而是它已經符合現有的 source of truth、PR 審查和發佈路徑。新增一個高權限 Hosting Control Plane，目前還抵銷不了額外狀態與基礎設施的成本。

反過來，如果要管理數十個應用程式，統一處理網域、資料庫、檔案、備份、專案隔離，也確實希望 Coding Agent 經由受限制的介面管理資源，PanelAlpha 的定位就合理許多。它不只是更花俏的 `docker compose up`，而是在嘗試將傳統 hosting panel 轉成 Agent 可以呼叫的基礎設施 API。

這次實驗停在安裝階段，對目前的選擇卻已足夠。它沒有回答「PanelAlpha 完整運作後好不好用」，但已回答我真正需要決定的事：如果目標只是將審查過的程式碼可靠地發佈到幾台伺服器，目前沒有理由只為了 AI 操作體驗，另外引入整套 VPS 控制平面。

以後再測，我會換資源更充裕的全新 VPS，先完成 `readonly / modify / full` 的 MCP 拒絕矩陣，再驗證失敗發佈、遠端備份還原與 telemetry 的實際行為。到那時，才適合討論長期 AI 維運入口，而不只是安裝體驗。
