macOS 开机自动启动服务配置文档
本文档介绍如何在 macOS 上使用 LaunchAgent 实现开机自动启动服务(uwsgi 和 nginx)。
目录
- 基础知识
- uwsgi 自动启动配置
- nginx 自动启动配置
- 常用管理命令
- 故障排查
- 附录
基础知识
LaunchAgent vs LaunchDaemon
| 特性 |
LaunchAgent |
LaunchDaemon |
| 启动时机 |
用户登录后 |
系统启动时(无需登录) |
| 权限 |
用户权限 |
root 权限 |
| 配置路径 |
~/Library/LaunchAgents/ |
/Library/LaunchDaemons/ |
| 适用场景 |
个人服务、开发环境 |
系统服务、生产环境 |
plist 文件命名规范
采用反向域名格式:com.公司名.项目名.服务名.plist
例如:
com.apple.nginx.plist
com.apple.hx.nginx.plist
nginx 自动启动配置
方案一:直接启动(推荐)
1. 创建 LaunchAgent 配置文件
nano ~/Library/LaunchAgents/com.apple.hx.nginx.plist
配置内容:
```xml name=com.apple.hx.nginx.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">
Label
com.apple.hx.nginx
ProgramArguments
/opt/homebrew/bin/nginx
-g
daemon off;
RunAtLoad
KeepAlive
StandardOutPath
/opt/homebrew/var/log/nginx/launch.out.log
StandardErrorPath
/opt/homebrew/var/log/nginx/launch.err.log
WorkingDirectory
/opt/homebrew
```
**重要说明:**
- **`-g "daemon off;"`**:让 nginx 在前台运行(LaunchAgent 要求)
- **`KeepAlive: true`**:nginx 崩溃时自动重启
---
#### 2. 加载和启动服务
```bash
# 确保日志目录存在
mkdir -p /opt/homebrew/var/log/nginx
# 设置文件权限
chmod 644 ~/Library/LaunchAgents/com.apple.hx.nginx.plist
# 验证 plist 格式
plutil -lint ~/Library/LaunchAgents/com.apple.hx.nginx.plist
# 加载服务
launchctl load ~/Library/LaunchAgents/com.apple.hx.nginx.plist
# 验证是否加载成功
launchctl list | grep com.apple.hx.nginx
# 查看进程
ps aux | grep nginx
# 测试访问
curl http://localhost
```
---
### 方案二:使用 shell 脚本启动
#### 1. 创建启动脚本
```bash
nano /opt/hx_analyze/server/start_nginx.sh
```
**脚本内容:**
```bash name=start_nginx.sh
#!/bin/bash
# 可选:延迟启动
# sleep 10
# 启动 nginx(前台运行)
exec /opt/homebrew/bin/nginx -g "daemon off;"
```
**设置执行权限:**
```bash
chmod +x /opt/hx_analyze/server/start_nginx.sh
```
---
### 方案二:使用 Homebrew Services(最简单)
如果 nginx 是通过 Homebrew 安装的:
```bash
# 启动并设置开机自启
brew services start nginx
# 查看所有服务状态
brew services list
# 停止服务
brew services stop nginx
# 重启服务
brew services restart nginx
```
Homebrew 会自动创建和管理 LaunchAgent,无需手动配置!
---
## 常用管理命令
---
### nginx 服务管理
```bash
# 启动服务
launchctl start com.apple.hx.nginx
# 停止服务
launchctl stop com.apple.hx.nginx
# 卸载服务
launchctl unload ~/Library/LaunchAgents/com.apple.hx.nginx.plist
# 重新加载服务
launchctl unload ~/Library/LaunchAgents/com.apple.hx.nginx.plist
launchctl load ~/Library/LaunchAgents/com.apple.hx.nginx.plist
# 查看服务状态
launchctl list | grep com.apple.hx.nginx
# 查看进程
ps aux | grep nginx
# 查看日志
tail -f /opt/homebrew/var/log/nginx/launch.err.log
# 测试 nginx 配置
/opt/homebrew/bin/nginx -t
# 重新加载 nginx 配置(不重启)
/opt/homebrew/bin/nginx -s reload
```
---
### macOS 新版命令(bootstrap/bootout)
macOS Big Sur 及更高版本推荐使用:
```bash
# 加载服务
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.apple.nginx.plist
# 卸载服务
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.apple.nginx.plist
# 查看服务详情
launchctl print gui/$(id -u)/com.apple.hx.analyze
```
---
## 故障排查
### 1. 验证 plist 文件格式
```bash
plutil -lint ~/Library/LaunchAgents/com.apple.nginx.plist
```
应该输出:`OK`
---
### 2. 检查文件权限
```bash
# 检查 plist 文件权限
ls -l ~/Library/LaunchAgents/com.apple.nginx.plist
# 应该是:-rw-r--r--
# 检查脚本权限
ls -l /opt/hx_analyze/server/start.sh
# 应该是:-rwxr-xr-x
# 修正权限
chmod 644 ~/Library/LaunchAgents/com.apple.nginx.plist
chmod +x /opt/hx_analyze/server/start.sh
```
---
### 3. 查看系统日志
```bash
# 查看 launchd 相关日志
log show --predicate 'subsystem == "com.apple.xpc.launchd"' --last 5m
# 查看特定服务日志
log show --predicate 'subsystem == "com.apple.xpc.launchd"' --last 5m | grep com.apple.xpc
# 实时监控系统日志
log stream --predicate 'subsystem == "com.apple.xpc.launchd"'
```
---
### 4. 查看服务日志
```bash
# nginx 日志
cat /opt/homebrew/var/log/nginx/launch.err.log
cat /opt/homebrew/var/log/nginx/error.log
cat /opt/homebrew/var/log/nginx/access.log
```
---
### 5. 手动测试脚本
在配置 LaunchAgent 之前,先手动测试脚本是否正常:
```bash
# 测试 nginx
/opt/homebrew/bin/nginx -t # 测试配置
/opt/homebrew/bin/nginx -g "daemon off;" # 前台运行测试
```
---
### 6. 常见错误及解决方案
| 错误 | 原因 | 解决方案 |
|------|------|----------|
| `Load failed: 5: Input/output error` | plist 格式错误或权限问题 | 1. 运行 `plutil -lint` 检查
2. 删除 `UserName` 字段(LaunchAgent 不需要)
3. 检查文件权限 |
| 服务加载成功但不运行 | 脚本路径错误或无执行权限 | 1. 检查路径是否正确
2. 运行 `chmod +x` 添加执行权限 |
| nginx 启动后立即退出 | 缺少 `daemon off;` 参数 | 在 ProgramArguments 中添加 `-g "daemon off;"` |
| 日志文件未生成 | 日志目录不存在 | 运行 `mkdir -p` 创建日志目录 |
---
## 附录
---
### B. plist 配置完整参考
```xml
Label
com.apple.hx.example
ProgramArguments
/bin/bash
/path/to/script.sh
RunAtLoad
KeepAlive
StandardOutPath
/path/to/out.log
StandardErrorPath
/path/to/err.log
WorkingDirectory
/path/to/working/dir
EnvironmentVariables
PATH
/usr/local/bin:/usr/bin:/bin
<!-- 定时执行(每隔 N 秒) -->
<!-- 注意:与 RunAtLoad 配合使用会导致重复执行 -->
<!-- <key>StartInterval</key>
<integer>3600</integer> -->
<!-- 定时执行(指定时间) -->
<!-- <key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>2</integer>
<key>Minute</key>
<integer>30</integer>
</dict> -->
</dict>
</plist>
---
### C. 文件和目录结构
/opt/hx_analyze/server/
├── start.sh # uwsgi 启动脚本
├── start_nginx.sh # nginx 启动脚本
├── uwsgi.ini # uwsgi 配置文件
└── log/
├── analyze.log # uwsgi 运行日志
├── launch.out.log # LaunchAgent 标准输出
├── launch.err.log # LaunchAgent 错误输出
├── nginx.out.log # nginx 标准输出
└── nginx.err.log # nginx 错误输出
~/Library/LaunchAgents/
├── com.apple.nginx.plist # uwsgi LaunchAgent
└── com.apple.hx.nginx.plist # nginx LaunchAgent
/opt/homebrew/var/log/nginx/
├── access.log # nginx 访问日志
├── error.log # nginx 错误日志
├── launch.out.log # LaunchAgent 标准输出
└── launch.err.log # LaunchAgent 错误输出
```
总结
最佳实践
- ✅ 先手动测试脚本,确保能正常运行
- ✅ 使用
plutil -lint 验证 plist 格式
- ✅ 查看日志文件排查问题
- ✅ 在 LaunchAgent 中不要使用
UserName 字段
- ✅ 重启电脑验证开机自启是否生效
文档版本: v1.0
最后更新: 2026-02-06
适用系统: macOS Big Sur 及更高版本