1. 前言
最近在公司做了个内部提效的飞书机器人,公司有台公共的mac mini,之前一直是手动打包好代码上传到mac mini上用 uv run python main.py 运行,可以说是非常不优雅了。
以前都是在 Linux 上用 systemctl 部署服务,没在 mac 弄过,查了一下 mac 系统上有个 launchd 用于管理服务,这篇文档记录一下第一次在 mac 上用 launchd 部署服务
2. launchctl 与 systemctl 的区别
| 功能 | systemctl | launchctl |
|---|---|---|
| 主要配置文件 | .service |
.plist |
| 启动服务 | systemctl start [name] |
launchctl bootstrap gui/$(id -u) [path] |
| 停止服务 | systemctl stop [name] |
launchctl bootout gui/$(id -u) [path] |
| 开机自启 | systemctl enable [name] |
只要 .plist 文件放到特定目录,默认加载 |
| 查看状态 | systemctl status [name] |
launchctl list [label] |
服务配置文件位置
macOS 使用 Property List (.plist) 文件来定义服务。根据你想让服务以什么权限运行,存放路径也不同:
-
用户级 Agent (
~/Library/LaunchAgents): 只有当前用户登录后才运行,以该用户权限运行。 -
系统级 Agent (
/Library/LaunchAgents): 任何用户登录后都会运行。 -
系统级 Daemon (
/Library/LaunchDaemons): 开机即运行,通常以 root 权限运行(适合 Web 服务器、数据库等)。
3. 配置文件的编写
创建 ~/Library/LaunchAgents/com.yingdao-fj.cyber-monkey.plist 文件,写入以下内容。
<?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.yingdao-fj.cyber-monkey</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/uv</string>
<string>run</string>
<string>python</string>
<string>main.py</string>
<string>--config</string>
<string>/Users/shadowbotfj/.cyber-monkey/config.yaml</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/shadowbotfj/project/cyber-monkey</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/dev/null</string>
<key>StandardErrorPath</key>
<string>/dev/null</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
<key>PYTHONUNBUFFERED</key>
<string>1</string>
</dict>
</dict>
</plist>