隔离的 Linux 虚拟机 (Apple Silicon)
在 macOS (Apple Silicon) 上的纯净 Linux 虚拟机中运行 hstack 流程,以实现可重复的验证。
如果你想在全新的隔离系统(无现有 hstack review-pr 基础、无宿主机工具链)中,使用 ~/.Kaiwu-stack 验证 hstack 或 Kaiwu 的 PR,在 Apple Silicon 芯片上最简便、可重复性最高的方法,是使用由 Lima 管理的 Linux 虚拟机(底层基于 Apple 的 Virtualization.framework)。
这种方案既能保证环境真正“纯净”,又能避免 Docker/容器常见的体验问题(如浏览器唤起、Expo 网络通信、文件监听等)。
方案 A(推荐):Lima + Ubuntu ARM64
1) 安装 Lima(macOS 宿主机)
brew install lima1b) 自动化冒烟测试(可选)
在 macOS 宿主机上运行(当前仓库,位于 apps/stack/):
./scripts/provision/macos-lima-hstack-smoke.sh happy-e2e验证内容(尽最大努力验证):
- 在完全隔离的沙盒中运行
hstack setup-from-source --profile=selfhost(无认证/无 tailscale/无自启动/无菜单栏) - 服务器健康检查端点(
/health) - UI 是否由 server-light 正常托管(
/返回 HTML) - 单体仓库工作树创建(
hstack wt new ...)
如果你需要进行多次重复测试,并记录每次迭代的日志和 JSON 元数据,请运行:
HSTACK_REPEAT_COUNT=5 ./scripts/provision/macos-lima-hstack-repeat-validation.sh happy-e2e报告目录树默认生成在 output/lima-validation-⟦K20⟧-⟦K21⟧/ 下。
说明:
- 该流程在虚拟机(Linux)内运行,默认使用
npx。 - 你可以固定待测版本:
HSTACK_VERSION=0.6.14 ./scripts/provision/macos-lima-hstack-smoke.sh happy-e2e。 - 如果正在测试 fork 分支,可以将运行器指向你 fork 仓库中的脚本原始链接:
HSTACK_RAW_BASE=https://raw.githubusercontent.com/⟦K22⟧/⟦K23⟧/⟦K24⟧/apps/stack ./scripts/provision/macos-lima-hstack-smoke.sh happy-e2e。 - 如果正在测试未发布的本地变更,可将打包好的 tarball 复制到虚拟机内并运行:
HSTACK_TGZ=./Kaiwu-dev-stack-*.tgz /tmp/linux-ubuntu-hstack-smoke.sh。
2) 创建并配置虚拟机(推荐脚本)
在 macOS 宿主机上运行(当前仓库,位于 apps/stack/):
./scripts/provision/macos-lima-vm.sh happy-test该脚本会在需要时创建虚拟机,并针对虚拟机默认使用的端口范围配置 localhost 端口转发。
(这一点至关重要,因为 Expo Web 应用使用了 WebCrypto API,需要像 http://localhost 这样的安全上下文环境。)
脚本还会调高虚拟机默认内存大小(以避免 Expo/Metro 遭遇 OOM 被杀,退出码为 code=137)。
如有需要可以覆盖该配置:
LIMA_MEMORY=12GiB ./scripts/provision/macos-lima-vm.sh happy-test端口范围说明:
review-pr运行在完全隔离的沙盒中(拥有独立的 hstack 主目录),因此写入虚拟机内部~/.Kaiwu-stack/env.local的虚拟机默认配置不会被自动读取。- 建议向
review-pr传递--vm-ports(或显式指定--stack-port-start=...),确保沙盒使用已转发的端口范围。
2b) 手动配置(可选)
limactl create --name happy-pr --tty=false template://ubuntu-24.04
limactl start happy-pr如果在虚拟机内运行 review-pr(Expo Web / Metro),请务必分配足够的内存(建议 8GiB 以上)。
在 macOS 宿主机上编辑 ~/.lima/happy-pr/lima.yaml 并设置:
memory: "8GiB"2c) 宿主机访问(端口与浏览器访问地址)
如果你想在 macOS 浏览器中打开 Kaiwu/Expo 的页面链接,请使用 localhost 端口转发。
原因在于:Expo Web 应用通过 expo-crypto 调用 WebCrypto(crypto.subtle)进行密钥派生等操作。
而浏览器仅在安全上下文(Secure Context)中开放 WebCrypto:
https://...http://localhost、http://127.0.0.1和http://*.localhost
如果你通过虚拟机的局域网 IP(如 http://192.168.x.y:PORT)访问页面,浏览器会将其判定为不安全,可能会触发如下报错:
TypeError: Cannot read properties of undefined (reading 'digest')。
配置端口转发(推荐)
在 macOS 宿主机上编辑实例配置:
limactl stop happy-pr || true
open -a TextEdit ~/.lima/happy-pr/lima.yaml添加 portForwards 配置段,将 hstack 虚拟机的端口范围转发至宿主机的 localhost:
portForwards:
# Stack/server ports (default VM range from our provision script)
- guestPortRange: [13000, 13999]
hostPortRange: [13000, 13999]
# Expo dev-server (web) ports (default VM range from our provision script)
- guestPortRange: [18000, 19099]
hostPortRange: [18000, 19099]随后重启虚拟机:
limactl start happy-pr可选:基于 IP 访问(仅在需要局域网访问时使用)
如果你确实需要通过虚拟机 IP 访问客户机服务(例如从另一台设备进行测试),可以启用 vzNAT:
limactl stop happy-pr || true
limactl start happy-pr --network vzNAT注意:基于 IP 的链接(如 http://192.168...)可能会导致仅限 Web 的加密流程异常,除非启用 HTTPS 或在浏览器开发者选项中进行特殊配置。
3) 准备虚拟机环境(Node 及构建依赖)
limactl shell happy-pr在虚拟机内部执行:
curl -fsSL https://raw.githubusercontent.com/wuji-labs/kaiwu/main/apps/stack/scripts/provision/linux-ubuntu-provision.sh -o /tmp/linux-ubuntu-provision.sh \
&& chmod +x /tmp/linux-ubuntu-provision.sh \
&& /tmp/linux-ubuntu-provision.sh --profile=Kaiwu3b)(可选)运行 hstack 开发环境配置向导
如果你的目标是开发功能/修改代码(而不仅仅是评审 PR),可以运行开发配置:
npx --yes -p @Kaiwu-dev/stack@latest hstack setup-from-source --profile=dev --bind=loopback说明:
- 该步骤会初始化工作区(克隆仓库、安装依赖、配置工作树/栈工具链)。
- 在 Linux 虚拟机中,通常建议使用
--no-mobile工作流(iOS dev-client 需要 Xcode/macOS 支持)。
4) 通过 npx(已发布的包)运行 review-pr
在虚拟机内部执行:
npx --yes -p @Kaiwu-dev/stack@latest hstack review-pr \
--repo=https://github.com/wuji-labs/kaiwu/pull/<PR_NUMBER> \
--vm-ports \
--no-mobile \
--keep-sandbox \
--verbose \
-- --bind=loopback说明:
--no-mobile可以让验证过程更加聚焦(Expo 移动端 dev-client 对宿主机环境有更多要求)。- 如果希望在执行失败后检查沙盒内容,还可以添加
--keep-sandbox。 - 如需完全复现,请固定版本号:
npx --yes -p @Kaiwu-dev/stack@0.3.0 hstack review-pr ... --vm-ports会强制将栈/服务器以及 Expo dev-server(Web)的端口限制在已转发的虚拟机端口范围内(与本文档中的portForwards配置相配套)。
可选:测试未发布的本地修改
如果你需要测试尚未发布到 npm 的代码修改:
- 在 Mac 上(代码仓库目录下)运行:
npm pack- 将生成的
Kaiwu-dev-stack-*.tgz复制到虚拟机内(方式不限),然后在虚拟机内运行:
npx --yes ./Kaiwu-dev-stack-*.tgz hstack review-pr ...方案 B:带图形界面的虚拟机(UTM)——需要“真实桌面环境”时的最简方案
如果你想要最接近真实用户的“评审者”体验(唤起浏览器等),图形界面虚拟机是不错的选择:
- 安装 UTM(macOS 宿主机):
brew install --cask utm - 创建 Ubuntu 24.04 ARM64 虚拟机(使用 UTM 向导)。
- 在虚拟机内执行相同的依赖初始化与
node bin/hstack.mjs review-pr ...。
方案 C:Apple“容器” / Docker
容器非常适合仅涉及服务端的验证,但通常不适合端到端的 review-pr 体验测试,原因在于:
- 在容器内打开宿主机浏览器较为繁琐
- Expo/开发服务器工作流及网络通信往往需要额外的端口映射以及宿主机交互
只有当你明确只需要“纯命令行”检查、且愿意手动在浏览器中打开链接时,才建议使用容器方案。
重置与彻底重来
彻底重置(推荐):重新创建虚拟机
在 macOS 宿主机上运行:
limactl stop happy-pr || true
limactl delete happy-pr
limactl create --name happy-pr --tty=false template:ubuntu-24.04
limactl start happy-pr然后按照本文档重新执行环境准备步骤(Node 及构建依赖)。
软重置:保留虚拟机,清除 hstack 状态
如果你希望在不重建虚拟机的情况下获得一个相对干净的环境,只需删除 hstack 主目录以及你所选的工作区:
在虚拟机内部执行:
rm -rf ~/.Kaiwu-stack ~/.Kaiwu如果你使用了 hstack setup-from-source --profile=dev 并且选择了自定义的工作区目录(位于 ~/.Kaiwu-stack/workspace 之外),也请一并将该目录删除。
说明与范围
- 本文档针对 Ubuntu ARM64 虚拟机上的 纯 Web 验证(
--no-mobile)。 - 通过
--mobile进行真机 iOS 测试需要配备 Xcode 的 macOS 宿主机(无法在 Linux 虚拟机内进行)。