先连通,再构建

从第一条 ssh
到第一次 archive

给刚拿到节点的开发者:先验证连接与工具链,再接入流水线。这里的命令都是操作示例,不是你的实时节点状态。

已有节点从第 1 步开始;凭据、到期时间与实际可用状态以控制台实时返回为准。

01 / 连接

先确认连的是你的物理节点

在控制台打开对应实例,核对节点、IP、SSH 端口与用户名。不要从旧工单复制凭据,也不要把登录密码写入仓库。

  1. 01

    核对实例信息

    进入控制台的实例详情,记录 IP、端口和当前凭据。下文用 NODE_IP、SSH_PORT 与 NODE_USER 表示这些值;执行前在本地终端赋值,不要原样照抄变量名作为地址。

  2. 02

    验证主机指纹

    第一次连接会询问是否信任主机。将显示的指纹与可信渠道提供的信息核对后再确认;无法核对就先提交工单。不要用关闭主机校验的参数绕过提示。

  3. 03

    改密码、配公钥

    首次登录后执行 passwd 修改当前用户密码。公钥可以传到节点,私钥始终留在本地。保留当前连接,用第二个终端验证公钥登录成功后,再调整认证策略。

把连接信息收进一个别名

在本地 ~/.ssh/config 写入以下配置,将三个大写字段换成实例详情中的实际值。IdentityFile 指向你本地已有的私钥文件;尚未创建密钥时,可先执行右侧的生成命令。

Host armshell-dev
  HostName NODE_IP
  User NODE_USER
  Port SSH_PORT
  IdentityFile ~/.ssh/armshell_ed25519
  IdentitiesOnly yes
  ServerAliveInterval 30
  ServerAliveCountMax 3

保存后用 ssh armshell-dev 连接。若主机指纹变更,先确认实例是否重新交付,不要直接删除记录后继续登录。

上传公钥,而不是私钥

下面的公钥写入命令在本地执行,要求别名已配置且密码登录可用。为密钥设置口令,并确保本地有安全备份。

ssh-keygen -t ed25519 -f ~/.ssh/armshell_ed25519
cat ~/.ssh/armshell_ed25519.pub | ssh armshell-dev \
'umask 077; mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys'
ssh -o PreferredAuthentications=publickey armshell-dev

登录后运行 whoami、sw_vers 和 df -h,确认用户、系统版本与可用磁盘空间。若权限不符合预期,先处理权限问题,再安装开发工具。

02 / 工具链

先跑通交互式构建,再交给 CI

确认目标 Xcode 已安装并完成首次启动配置。下面展示命令与输出的格式,版本、SDK 和证书名称需以你的节点与项目为准,不代表预装清单。

dev@armshell-tokyo
$ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
$ xcode-select -p
/Applications/Xcode.app/Contents/Developer

$ sudo xcodebuild -runFirstLaunch
$ xcodebuild -showsdks
iOS SDKs:
    iOS 18.0                       -sdk iphoneos18.0
iOS Simulator SDKs:
    Simulator - iOS 18.0           -sdk iphonesimulator18.0

$ bundle exec fastlane match development --readonly
[09:12:01]: Successfully decrypted certificates repo
[09:12:03]: Installing certificate...
[09:12:05]: Installing provisioning profile...
[09:12:06]: All required keys, certificates and provisioning profiles are installed

$ xcodebuild -workspace App.xcworkspace -scheme App \
    -configuration Release -destination 'generic/platform=iOS' \
    -archivePath "$HOME/build/App.xcarchive" archive
** ARCHIVE SUCCEEDED **

版本选择是节点级操作

xcode-select 修改默认开发者目录,会影响同机其他任务。多版本并行时,优先在单次任务中设置 DEVELOPER_DIR,并在日志开头输出 xcodebuild -version,避免交接后使用错误工具链。

签名要能在当前会话解锁

示例假设项目已配置 fastlane、Gemfile 与证书仓库访问权限。先用只读模式同步已有证书;构建用户需要能读取并解锁自己的钥匙串。签名失败时先查权限与描述文件,不要反复生成新证书。

archive 不等于发布完成

先确认工作区与 scheme 名称,再检查 archive 产物。导出安装包还需要与分发方式匹配的导出配置。首次构建通过后记录 Xcode 版本、依赖锁文件和完整命令,再迁入流水线。

03 / 图形界面

需要操作界面时,再打开桌面会话

命令行适合传输、构建与日志检查。首次配置工具、检查钥匙串提示或调试界面时,再使用 macOS 图形界面。桌面入口只在登录后的实例详情中提供。

开启与权限

通过实例已提供的桌面入口进入系统,在“系统设置 → 通用 → 共享”检查“屏幕共享”。仅允许指定用户访问,不要开启所有用户访问。若屏幕共享与远程管理互斥,先核对当前配置,不要同时修改两项。

首次无法进入桌面时,通过控制台工单请求检查,不要在不熟悉的情况下批量修改系统远程访问服务。

登录控制台提交工单

客户端与连接路径

本地为 macOS 时可使用系统“屏幕共享”客户端;其他系统可使用兼容 VNC 协议、支持安全连接的客户端。优先使用实例提供的安全访问方式,不要把桌面服务直接暴露给不受信任的网络。

已确认节点 VNC 服务监听在本机 5900 端口时,可用下方 SSH 隧道,把客户端连接到本地 127.0.0.1:5901。

ssh -N -L 5901:127.0.0.1:5900 armshell-dev

先降低画面负担

初次连接建议从 1440 × 900 分辨率与单屏开始,关闭不必要的动画。带宽有限时先降低画质或帧率;提升分辨率不会改善构建速度,只会增加画面传输量。

不同编码与画面变化会影响带宽占用,没有适用于所有任务的固定带宽保证。连接卡顿时,先暂停大文件上传,再对比 SSH 是否也有延迟。

桌面操作与命令行使用同一台独享物理机。
04 / 持续集成

让 Runner 使用你刚验证过的环境

用专门的 macOS 构建用户注册 Runner。先以单任务并发验证依赖、签名和产物回传,再根据内存与磁盘使用情况增加并发;不要将不受信任的合并请求交给持有发布凭据的执行器。

GitLab:注册 shell executor

先安装适合 Apple Silicon 的 GitLab Runner。下面命令假设可执行文件已在当前用户的 PATH 中,并已在 CI 管理界面创建 Runner,取得服务器地址与认证令牌。

read -r CI_SERVER_URL
read -rs RUNNER_TOKEN
gitlab-runner register --non-interactive \
  --url "$CI_SERVER_URL" \
  --token "$RUNNER_TOKEN" \
  --executor shell
unset RUNNER_TOKEN
gitlab-runner verify
gitlab-runner install
gitlab-runner start
gitlab-runner status

在 CI 管理界面设置明确标签,例如 macos-arm64 与项目要求的 Xcode 版本。作业标签应与 Runner 匹配。先执行 whoami、xcodebuild -version,再运行正式构建。

GitHub Actions:注册自托管节点

在仓库或组织的 Runner 设置中获取 macOS ARM64 安装包与当次注册命令。先完成下载、校验与解压,再进入解压目录运行以下命令;两个变量从设置页获取。

read -r REPOSITORY_URL
read -rs RUNNER_TOKEN
./config.sh --url "$REPOSITORY_URL" \
  --token "$RUNNER_TOKEN" \
  --labels macos-arm64 --unattended
unset RUNNER_TOKEN
./svc.sh install
./svc.sh start
./svc.sh status

工作流使用 runs-on: [self-hosted, macOS, ARM64],有自定义标签时一并指定。注册令牌与运行服务不是同一件事;配置成功后仍需检查服务状态和一条真实测试作业。

launchd 常驻:安装服务后,检查实际加载项

上面的服务安装命令会按各 Runner 的实现创建 macOS 服务配置。优先使用它们提供的管理命令,不要同时手写第二份服务启动同一个 Runner。

用户级 LaunchAgent 通常随该用户登录加载。若需要重启后无人值守运行,先确认对应 Runner 的服务支持方式、登录状态和钥匙串策略,不能把“当前在线”当成“重启后一定可用”。

ls "$HOME/Library/LaunchAgents"
launchctl print "gui/$(id -u)"
gitlab-runner status
./svc.sh status

在实际 Runner 目录分别执行适用的检查命令。CI 的非交互环境可能没有终端里的 PATH;把 Homebrew、Ruby 与 Xcode 路径写入受版本管理的构建脚本,并避免把令牌打印进日志。

05 / 数据

只同步变化,把备份留在节点之外

源码优先通过仓库克隆。大目录、构建产物与不适合进入仓库的文件,可通过 SSH 上的 rsync 增量同步。租用节点是工作环境,不应是唯一的数据副本。

先预演,再上传

先检查两端 rsync --version。以下使用常见基础选项:保留尾部斜杠表示同步目录内容,排除项按项目调整。先读完预演输出,再移除 -n。

rsync -avzn --exclude '.git/' --exclude 'build/' \
  ./project/ armshell-dev:~/work/project/

rsync -avz --exclude '.git/' --exclude 'build/' \
  ./project/ armshell-dev:~/work/project/

rsync -avz armshell-dev:~/build/ ./artifacts/

不要未经确认加入 --delete,它会删除目标端多余文件。密钥、证书和包含敏感数据的日志,应单独管理访问权限,不要夹在整个工作目录里公开分发。

并联加购不是互联网加速器

Thunderbolt 5 并联用于需要多台节点协同处理大文件的场景。它不替代从你本地网络到节点的互联网连接,也不会自动加速任意 rsync 任务。下单前说明参与节点、数据规模与工作流,确认适用连接方式。

需要更多工作空间时,可以评估 +1TB SSD 或 +2TB SSD 加购。扩展磁盘不等于备份:代码、产物和证书仍应有节点外副本。

每次发布后验证回传文件可读;重要产物记录校验值。到期前至少完成一次独立恢复验证,而不仅是看同步命令返回成功。

06 / 账户与周期

把到期检查放进发布前清单

在控制台查看订单、实例到期时间、账单与续费操作。节点全年 365 天正常运行;你自己的租用周期与订单状态,仍需按控制台记录管理。

检查周期与时间

服务支持按天、按周、按月、按季计费。核对控制台显示的起止时间与时区,并为构建、回传和备份留出余量。不要等长任务跑到一半才处理续费,也不要假定系统一定会自动扣款。

以订单明细和到期时间为核对依据。

先确认变更,再迁移

升级机型、增加存储或调整周期前,先查看当前订单可用操作、报价与生效方式。不要假定所有变更都会原地即时完成。涉及环境迁移时,先保存依赖清单、签名配置和数据副本。

未明确的折算与生效规则,通过工单确认。

核对支付与到账

仅支持 USDT-TRC20 与 Visa / Mastercard / Amex(经 Stripe),统一以美元(USD)结算,实际可用网关以后端接口返回为准。链上支付核对网络、金额与收款信息;卡支付按账单页面完成验证。

状态未更新时,附订单号和交易记录提交工单。
出错时,按层排查

先分清连接问题,还是任务问题

提交问题时附上订单号、节点、发生时间与时区、执行命令和完整错误段。可以提供截图或脱敏终端输出,但不要发送密码、私钥、令牌或完整支付卡信息。

SSH 超时,从哪里开始查?
  1. 回到实例详情核对 IP、端口、订单与运行状态,排除连接旧地址。
  2. 本地执行 ssh -vvv armshell-dev,区分超时、拒绝连接与认证失败;三者不是同一种故障。
  3. 检查本地网络与出口规则,换一条可信网络复测。ICMP 不通不能单独证明 SSH 服务不可用。
  4. 若卡在认证阶段,检查用户名、私钥权限与公钥归属;若一直超时,携带脱敏日志提交工单,不要不断重置密码。
Xcode 下载或依赖拉取很慢,怎么区分?
  1. 先用 df -h 检查磁盘空间,确保安装包、解压与旧版本并存所需空间充足。
  2. 区分 Xcode 安装包传输、依赖仓库拉取和首次编译;编译日志停顿不一定在下载。
  3. 使用可信来源的完整安装包,并核对完整性。大文件传输避免和备份任务并发争用带宽。
  4. 记录来源类型、文件大小、开始时间与错误,不要发送包含访问令牌的下载地址。需要检查节点网络时,将这些信息交给工单。
远程桌面连上了,却只有黑屏?
  1. 先确认 SSH 是否正常,分清整台节点不可达,还是只有桌面会话异常。
  2. 检查连接用户是否有屏幕共享权限、是否已有有效图形会话;降低分辨率后重新连接。
  3. 若使用 SSH 隧道,确认隧道终端仍在运行,客户端连接的是本地映射端口,而不是节点的其他端口。
  4. 不要直接强制重启正在构建的节点。先保存可获取的日志,说明是否能看到登录界面,再提交工单检查。
Runner 掉线,或在线但不接任务?
  1. 先查服务状态与进程日志,再查 CI 管理界面。节点能 SSH 登录,不代表 Runner 服务正在运行。
  2. 在线但不接任务时,检查项目权限、Runner 标签、工作流选择条件和保护分支设置。
  3. 重启后掉线时,检查 launchd 加载域与构建用户登录状态;手动终端启动不能代替常驻服务。
  4. 任务启动后失败时,输出用户、PATH、Xcode 版本与工作目录,检查钥匙串和目录权限。不要把 Runner 反复注销重建作为第一步。

ssh 已连通,问题还没解决?

把报错交给我们,把上下文一起带上

选型与售前问题可以联系邮箱;已有订单的技术与账单问题,登录控制台提交工单,方便关联实例与处理记录。