我现在的生产发布链已经比较固定:代码进 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 磁盘的机器上,安装超过两小时仍停在 Engine 安装阶段,最后记录的进度是 70%,我主动终止了后续实验。

这并不能证明 PanelAlpha “装不上”。它真正给我的信息是:这不是一个轻量的 AI 命令执行器,而是一套会进入 Docker、网络、防火墙、项目隔离、备份和监控边界的 Hosting Control Plane。安装没跑完,反而足够让我重新判断它是否应该拿来替代现有的 Self-hosted 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,而且 resolv.conf 本来就是外部 DNS,所以本次运行前后 DNS 文件没有发生可观察变化。源码能力和这一次机器上真正发生的事,需要分开写。

安装停在 70%,但宿主机已经不是原来的状态

实验结束前,我重新采集了一次机器状态。那时 Docker Engine 已经安装完成,版本是 29.8.2;PanelAlpha 的进度文件仍显示:

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 把三个权限模式按 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 的动态拒绝测试,所以不会说这些保护可以或不可以被绕过。

它给我的工程提醒更简单:给 Coding Agent 设计基础设施权限时,“不允许 DELETE”并不等于“不会覆盖重要状态”。恢复备份、把 staging 推到 live、重建项目,都可能通过 POST 完成。真要把 Agent 接进去,我会从 readonly 起步,再显式收窄 toolset 和 denylist,而不是只看 readonly / modify / full 三个名字。

备份与遥测这次也只停留在源码 / 官方文档边界。官方 Backups 文档 明确说没有内置定时计划,需要外部 cron 等调度;恢复会覆盖当前项目状态。Telemetry 文档则区分了 pae telemetry:disable 和将 PANELALPHA_MONITORING= 留空:前者会停掉计划的六小时健康巡检,后者官方描述为保留本地巡检但不向监控端点发送报告。这些行为我没有动态执行,只能当作 v2.1.1 的文档事实。

我现在不会拿它替换 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 审查、发布路径已经对齐,新增一个高权限 Hosting Control Plane 暂时没有抵消它带来的额外状态与底座成本。

反过来,如果要管理几十个应用、需要统一域名、数据库、文件、备份、项目隔离,并且确实希望 Coding Agent 通过一个受约束的接口管理这些资源,PanelAlpha 的定位就合理得多。它并不是一个更花哨的 docker compose up,而是在尝试把传统 hosting panel 变成 Agent 可以调用的基础设施 API。

这次实验最终停在安装阶段,我反而觉得足够了。它没有回答“PanelAlpha 完整跑起来以后好不好用”,但已经回答了我最初真正需要决定的事:如果目标只是把经过审查的代码可靠地发布到自己的几台服务器,我目前没有理由为了 AI 操作体验额外引入一整套 VPS 控制面。

如果以后再测,我会换成资源更充足的全新 VPS,第一件事也不会是部署真实项目,而是先完成 readonly / modify / full 的 MCP 拒绝矩阵,再测试失败发布、远端备份恢复和 telemetry 的实际行为。到那一步,才能讨论它是否适合作为长期的 AI 运维入口,而不只是讨论安装体验。