devAlice
← Mac

Brewfile 管理 — `brew bundle` で Mac 開発環境をコード化して再現する

Mac のセットアップを 1 ファイルに固定する Brewfile パターン。dump → cleanup → install を別マシンで一巡させる完全サイクル。

新しい Mac をセットアップするたびに brew install を 1 行ずつ打ち込むのは非効率だ。brew bundle を使えば、1 つの Brewfile に brew フォーミュラ、cask、VS Code 拡張機能、App Store アプリまでまとめて再現できる。このパターンを身につければ、マシン移行やチームメンバーのオンボーディングが 30 分以上短縮される。Brewfile の本質はパッケージリストではなく、環境のコード化にあると考える — 以前はマシンごとに手動でインストールしていたが、いまでは Brewfile 一つで完全に再現できるからこそ、環境の差異で詰まることがなくなった。

このガイドは macOS 14 以降 / Homebrew 4.x を対象とする。Mac 初期セットアップ の後に行う 環境をコードとして固定するステップ だ。

TL;DR

  1. brew bundle dump --describe で現在の状態を Brewfile にスナップショット
  2. 手動で整理(重複・テスト用パッケージを削除)→ Git にコミット
  3. 新しい Mac で: brew bundle install --file=./Brewfile → 完了
  4. 定期的に 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=./Brewfile

1. Brewfile の基本構文 — 5 分

内部は Ruby DSL だが、実際に使うキーワードは 5 つだけ。

# 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 (auto-generated)
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 は現在インストールされているすべてをキャプチャするため、ノイズが混入しがちだ。整理チェックリスト:

  1. 使わなくなったテスト用パッケージ → 削除
  2. 言語ランタイムmise で管理する場合は削除(例: nodepython@3.x
  3. 仕事用と個人用Brewfile.work / Brewfile.personal に分割
  4. セクションコメントを追加

10 分の投資が将来の 1 時間のセットアップを省く。


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 --quiet

4. Brewfile にないパッケージを削除する — cleanup — 5 分

Brewfile を唯一の情報源とするために、リストにないものを削除する。

# ドライラン — 何が削除されるかを確認
brew bundle cleanup --file=./Brewfile
 
# 実際に削除する — 慎重に
brew bundle cleanup --file=./Brewfile --force

⚠️ --force は即座にアンインストールする。Brewfile が完全に整理されたに実行すること。そうでないと再インストールが必要になる。


5. 分割戦略 — 仕事用 / 個人用 / 実験用

1 つの大きな 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 / シェルスクリプト経由

# ~/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=./Brewfile

7. 自動化 — brew services+macOS LaunchAgent

毎日 1 回 auto-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. トラブルシューティング

「Error: Cask 'X' is not installed」(cleanup 中)

cask がすでに別の方法で削除されている。brew bundle cleanup --force を再度実行して整合させる。

dump が意図しないパッケージを大量に拾う

古い推移的依存関係がトップレベルとして表示される。整理する:

brew autoremove   # 依存関係としてのみ使われているリーフパッケージを削除
brew bundle dump --force --describe  # 再 dump

App Store アプリが dump に現れない

mas-cli がない。brew install mas を実行してから再 dump する。

インストール中に一部の cask が SHA-256 で失敗する

Homebrew が cask 定義を更新した直後によく起きる。brew update してリトライ。


次のステップ

参考リンク

更新履歴

  • 2026-05-12 — 初稿(devAlice M2 シード展開)