主题
macOS 部署
适合演示、试用和内部验证。macOS 不建议作为正式生产服务器:休眠会中断服务,系统更新可能重启机器。
使用交付包:
| 芯片 | 包 | 确认方式 |
|---|---|---|
| Apple 芯片(M1 / M2 / M3 / M4 …) | darwin-arm64.zip | uname -m 输出 arm64 |
| Intel 芯片 | darwin-amd64.zip | uname -m 输出 x86_64 |
Apple 芯片也能跑 amd64 包
装了 Rosetta 2 时,Apple 芯片可以运行 darwin-amd64 包,但性能较差,建议用对应的包。
1. 准备
1.1 放置文件
bash
mkdir -p ~/apexpm
unzip ~/Downloads/darwin-arm64.zip -d ~/apexpm
cd ~/apexpm
chmod +x apexpm start.sh stop.sh
mkdir -p data
cp ~/Downloads/license.lic data/license.lic不要放在「桌面」「文稿」「下载」或 iCloud 同步目录
这些目录受 macOS 隐私保护(TCC)限制,launchd 启动的进程没有权限读写,会报 operation not permitted。放在 ~/apexpm 这类普通目录里。
1.2 解除 Gatekeeper 隔离
程序没有经过 Apple 公证,从网络下载后首次运行会被拦截。执行一次:
bash
xattr -dr com.apple.quarantine ~/apexpm1.3 确认授权 IP
bash
ifconfig | grep "inet " | grep -v 127.0.0.1签发授权时提供的 IP 必须在列表里。Mac 连 Wi-Fi 时 IP 经常变化,演示机请在路由器上绑定固定 IP,否则换个网络授权就会失效。
常见错误
| 现象 | 原因 | 处理 |
|---|---|---|
| 弹窗「无法打开 apexpm,因为 Apple 无法检查其是否包含恶意软件」 | Gatekeeper 隔离 | 执行 1.2;或「系统设置 → 隐私与安全性」底部点「仍要打开」 |
zsh: killed ./apexpm | 同上,被系统直接终止 | 执行 1.2 |
zsh: bad CPU type in executable | Intel Mac 用了 arm64 包 | 换 darwin-amd64 包 |
zsh: permission denied: ./apexpm | 没有可执行权限 | chmod +x apexpm |
2. 配置
bash
cd ~/apexpm
cp config.example.yaml config.yaml
open -e config.yaml # 用文本编辑打开文本编辑的格式
「文本编辑」默认可能存成 RTF 格式,保存时选「格式 → 制作纯文本」。更稳妥的做法是用 nano config.yaml 或 VS Code 编辑。
macOS 上至少改这几项:
| 字段 | 怎么改 |
|---|---|
jwt.secret | openssl rand -hex 32 生成后填入 |
server.port | macOS 12 以上的「隔空播放接收器」占用 5000 / 7000 端口,默认的 9000 不受影响;改端口时避开这两个 |
server.public_base_url | 填本机当前的局域网 IP |
字段完整说明见配置文件 config.yaml。
先前台试跑
bash
cd ~/apexpm
./apexpm另开终端执行 curl -fsS http://127.0.0.1:9000/health,正常后 Ctrl+C 停止。首次运行时如果弹出「是否允许 apexpm 接受传入网络连接」,点「允许」,否则局域网内其他电脑访问不到。
也可以直接用 ./start.sh / ./stop.sh 后台运行(用法与 Linux 相同),但不会开机自启。
3. 用 launchd 托管
创建 ~/Library/LaunchAgents/com.apexpm.server.plist,把其中的 你的用户名 换成 whoami 的输出:
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apexpm.server</string>
<key>ProgramArguments</key>
<array>
<string>/Users/你的用户名/apexpm/apexpm</string>
</array>
<!-- 必须是部署目录:程序在这里找 config.yaml 并创建 data/ -->
<key>WorkingDirectory</key>
<string>/Users/你的用户名/apexpm</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
</dict>
<key>StandardOutPath</key>
<string>/Users/你的用户名/apexpm/apexpm.log</string>
<key>StandardErrorPath</key>
<string>/Users/你的用户名/apexpm/apexpm.log</string>
</dict>
</plist>加载并启动:
bash
plutil -lint ~/Library/LaunchAgents/com.apexpm.server.plist # 检查格式
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.apexpm.server.plist
launchctl print gui/$(id -u)/com.apexpm.server | grep -E "state|pid|last exit"日常操作:
bash
launchctl kickstart -k gui/$(id -u)/com.apexpm.server # 重启
launchctl bootout gui/$(id -u)/com.apexpm.server # 停止并卸载
tail -f ~/apexpm/apexpm.logLaunchAgent 在用户登录后才启动。希望开机不登录就运行,需把 plist 放到 /Library/LaunchDaemons/、加上 UserName 键,并用 sudo launchctl bootstrap system ... 加载。
防止休眠中断服务:「系统设置 → 电池(或节能)」里关闭自动睡眠,或临时执行 caffeinate -s &。
常见错误
| 现象 | 原因 | 处理 |
|---|---|---|
plutil 报 Encountered unknown tag 等 | plist 格式错 | 按报错行号修正 |
Bootstrap failed: 5: Input/output error | 服务已加载过,或 plist 有错 | 先 launchctl bootout gui/$(id -u)/com.apexpm.server 再 bootstrap |
last exit code = 78 | 可执行文件或工作目录不存在或无权限 | 核对 plist 里的两个路径,确认用户名替换正确 |
日志 operation not permitted | 部署目录在受保护目录下 | 按 1.1 移到 ~/apexpm |
| 进程反复重启 | 启动即退出 | tail -50 ~/apexpm/apexpm.log 看 fatal 日志,对照故障排查总表 |
| 局域网其他电脑访问不到 | macOS 防火墙拦截 | 「系统设置 → 网络 → 防火墙 → 选项」里允许 apexpm 传入连接 |
升级
bash
cd ~/apexpm
launchctl bootout gui/$(id -u)/com.apexpm.server # 或 ./stop.sh
cp -a data "data.bak-$(date +%Y%m%d-%H%M%S)" # 必做
unzip -o ~/Downloads/darwin-arm64.zip apexpm -d .
chmod +x apexpm && xattr -d com.apple.quarantine apexpm 2>/dev/null
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.apexpm.server.plist # 或 ./start.sh
curl -fsS http://127.0.0.1:9000/health完整说明与回滚见版本升级。