Brewfile 管理 — 用 `brew bundle` 将 Mac 开发环境代码化
一种将 Mac 配置锁定到单个文件的 Brewfile 模式。dump → cleanup → install,完整循环,换机一步到位。
每次配置新 Mac 都要逐行敲 brew install,效率极低。brew bundle 让一个 Brewfile 将 brew 公式、cask、VS Code 扩展,甚至 App Store 应用打包成可复现的配置。掌握这一模式后,换机和团队成员入职的时间能缩减数个半小时。
我认为 Brewfile 的价值不只是自动化安装,而是把开发环境变成可审计的代码。以前环境存在于脑子里和操作历史里;如今通过 brew bundle,环境变成了 Git 可以追踪的文件,因为那个文件才是环境的单一真实来源。
本指南适用于 macOS 14+ / Homebrew 4.x,是 Mac 初始配置 之后的将环境冻结为代码步骤。
TL;DR
- 用
brew bundle dump --describe将当前状态快照到 Brewfile - 手动编辑(删除重复项和测试包)→ 提交到 Git
- 在新 Mac 上:
brew bundle install --file=./Brewfile→ 完成 - 定期
brew bundle cleanup删除不在 Brewfile 中的内容
前提条件
- Homebrew 4.x 已安装 — 参见 Mac 初始配置
- (可选)GitHub 仓库或 Gist(用于存储 Brewfile)
- (可选)
mas-cli— 如需打包 Mac App Store 应用,运行brew install mas
下载示例 Brewfile
devAlice 推荐的基础配置 — 下载后根据你的环境修改。
Brewfile# 1. 下载
curl -fsSL https://devalice.jaceclub.com/assets/mac/brewfile-management/Brewfile.example -o Brewfile
# 2. 验证 SHA-256
shasum -a 256 Brewfile
# 期望值:2b54214d29391d15666fe5e15768aa2e6e6eabea8b3c772989d6e1216a816c5f
# 3. 检查(查看包含哪些包;根据你的环境编辑)
less Brewfile
# 4. 应用
brew bundle install --file=./Brewfile1. Brewfile 语法基础 — 5 分钟
底层是 Ruby DSL,但实际上只需要掌握五个关键词。
# Brewfile
# tap — 额外的仓库
tap "homebrew/bundle"
tap "homebrew/services"
# brew — 公式(CLI 工具)
brew "git"
brew "gh"
brew "mise"
# 支持可选参数
brew "postgresql@16", restart_service: :changed
brew "redis", start_service: true
# cask — GUI 应用
cask "visual-studio-code"
cask "rectangle"
# Mac App Store(需要 mas-cli)
mas "Xcode", id: 497799835
# VS Code 扩展(与 mas 类似语法)
vscode "dbaeumer.vscode-eslint"
vscode "esbenp.prettier-vscode"注释 + 分区
# ─── CLI ──────────────────────────────────────
brew "git"
brew "gh"
# ─── GUI ──────────────────────────────────────
cask "visual-studio-code"分区分隔符对后续维护大有裨益——提交后 diff 一目了然。
2. 从当前状态生成 Brewfile — dump — 3 分钟
如果你已经有一台配置完善的机器,可以一次性快照。
# 在当前目录创建 Brewfile(--force 覆盖已有文件)
brew bundle dump --force --describe
# --describe 为每行添加 # 注释 — 可读性提升示例输出:
# ./Brewfile(自动生成)
tap "homebrew/services"
brew "git"
# Distributed revision control system
brew "gh"
# GitHub command-line tool
brew "jq"
# Lightweight and flexible command-line JSON processor
brew "mise"
# Polyglot runtime manager (asdf rust clone)
cask "visual-studio-code"
# Open-source code editor手动整理 dump 结果
新 dump 会捕获当前所有已安装的内容,通常包含不少冗余。整理清单:
- 不再使用的测试包 → 删除
- 语言运行时 → 如果用
mise管理,就删掉(如node、python@3.x) - 工作与个人 → 拆分为
Brewfile.work/Brewfile.personal - 添加分区注释
现在投入 10 分钟,未来省下一个小时的配置时间。
3. 在另一台机器上应用 — install — 10-30 分钟
在包含 Brewfile 的目录中,在新机器上(或清理后):
brew bundle install --file=./Brewfile
# 或使用绝对路径
brew bundle install --file=$HOME/dotfiles/Brewfile
# 已安装的项目会跳过(幂等)首次运行以 cask 下载为主(每个约 50-200MB)。预计需要 10-30 分钟。
逐步查看 — --verbose
brew bundle install --file=./Brewfile --verbose只显示失败 — --quiet
brew bundle install --file=./Brewfile --quiet4. 删除不在 Brewfile 中的包 — cleanup — 5 分钟
要让 Brewfile 成为唯一真实来源,删除未列出的所有内容。
# 演习 — 查看将会删除什么
brew bundle cleanup --file=./Brewfile
# 实际删除 — 谨慎操作
brew bundle cleanup --file=./Brewfile --force⚠️
--force会立即卸载。只在 Brewfile 完全整理好之后运行;否则可能需要重新安装。
5. 拆分策略 — 工作 / 个人 / 实验
单一的 Brewfile 最终会变得臃肿。按场景拆分。
~/dotfiles/
├── Brewfile # 通用(CLI 必需品)
├── Brewfile.work # 仅工作(Slack、Zoom...)
├── Brewfile.personal # 个人(游戏启动器...)
└── Brewfile.optional # 偶尔使用
一起应用
cd ~/dotfiles
brew bundle install --file=./Brewfile
brew bundle install --file=./Brewfile.work
brew bundle install --file=./Brewfile.personal或通过 Makefile/shell 脚本
# ~/dotfiles/bundle.sh
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
for f in Brewfile Brewfile.work Brewfile.personal; do
[ -f "$f" ] && brew bundle install --file="./$f"
done
echo "✓ 所有 Brewfile 已应用"6. Git 版本控制 — 3 分钟
Brewfile 是任何 dotfiles 仓库的核心文件。
cd ~/dotfiles
git init
git add Brewfile Brewfile.*
git commit -m "feat: initial Brewfile baseline"
git remote add origin git@github.com:<user>/dotfiles.git
git push -u origin main之后添加/删除包时:
brew bundle dump --force --describe # 刷新
git diff Brewfile # 查看变更
git commit -am "feat: add postgresql + redis"
git push在新机器上:
git clone git@github.com:<user>/dotfiles.git ~/dotfiles
cd ~/dotfiles
brew bundle install --file=./Brewfile7. 自动化 — brew services + macOS LaunchAgent
每天自动 dump 一次,防止 brew 状态漂移。
~/Library/LaunchAgents/dev.local.brewdump.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>dev.local.brewdump</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-lc</string>
<string>cd $HOME/dotfiles && /opt/homebrew/bin/brew bundle dump --force --describe</string>
</array>
<key>StartCalendarInterval</key>
<dict><key>Hour</key><integer>22</integer><key>Minute</key><integer>0</integer></dict>
</dict>
</plist>launchctl load ~/Library/LaunchAgents/dev.local.brewdump.plist每天 22:00 自动 dump。每天早上 git diff 查看隔夜变化。
8. 故障排除
cleanup 时提示「Error: Cask 'X' is not installed」
该 cask 已在其他地方删除。重新运行 brew bundle cleanup --force 使状态重新一致。
Dump 捕获了太多意外的包
旧的传递依赖显示为顶级包。整理方法:
brew autoremove # 删除仅作为依赖项使用的叶包
brew bundle dump --force --describe # 重新 dumpApp Store 应用未出现在 dump 中
mas-cli 未安装。运行 brew install mas 后重新 dump。
某些 cask 在安装时 SHA-256 校验失败
Homebrew 更新 cask 定义后可能发生。运行 brew update 后重试。
下一步
- Mac 初始配置 — Homebrew/SSH 设置
- Mac dotfiles — 与 Brewfile 一起管理的 shell/git 设置
- Mac 开发工具链 — 通过 mise 管理语言运行时
参考资料
brew bundle(官方)- Homebrew Cask
mas-cli— Mac App Store CLI
更新日志
- 2026-05-12 — 初始版本(devAlice M2 种子扩展)