devAlice
← Mac

Brewfile-Verwaltung — Mac-Entwicklungsumgebung als Code mit brew bundle reproduzieren

Ein Brewfile-Muster, das dein Mac-Setup in einer einzigen Datei fixiert. dump → cleanup → install auf einem anderen Gerät, ein vollständiger Zyklus.

Bei jedem neuen Mac-Setup brew install Zeile für Zeile einzutippen ist ineffizient. brew bundle ermöglicht es, mit einem einzigen Brewfile brew-Formeln, Casks, VS Code-Erweiterungen und sogar App-Store-Apps zu bündeln und reproduzierbar zu machen. Wer das Muster einmal verinnerlicht hat, spart bei Gerätewechseln und beim Onboarding neuer Teammitglieder jeweils rund 30 Minuten.

Dieser Leitfaden richtet sich an macOS 14+ / Homebrew 4.x. Er ist der Schritt Umgebung als Code einfrieren nach dem Mac-Ersteinrichtung.

TL;DR

  1. brew bundle dump --describe verwenden, um den aktuellen Zustand in einem Brewfile zu erfassen
  2. Manuell bearbeiten (Duplikate und Testpakete entfernen) → in Git committen
  3. Auf einem neuen Mac: brew bundle install --file=./Brewfile → fertig
  4. Regelmäßig brew bundle cleanup ausführen, um alles zu entfernen, was nicht im Brewfile steht

Voraussetzungen

  • Homebrew 4.x installiert — siehe Mac-Ersteinrichtung
  • (Optional) Ein GitHub-Repo oder Gist (zum Speichern des Brewfiles)
  • (Optional) mas-clibrew install mas, wenn du auch Mac App Store-Apps bündeln möchtest

Beispiel-Brewfile herunterladen

Die von devAlice empfohlene Basislinie — herunterladen und an deine Umgebung anpassen.

Brewfile
# 1. Herunterladen
curl -fsSL https://devalice.jaceclub.com/assets/mac/brewfile-management/Brewfile.example -o Brewfile
 
# 2. SHA-256 verifizieren
shasum -a 256 Brewfile
# Erwartet: 2b54214d29391d15666fe5e15768aa2e6e6eabea8b3c772989d6e1216a816c5f
 
# 3. Prüfen (welche Pakete enthalten sind; an die eigene Umgebung anpassen)
less Brewfile
 
# 4. Anwenden
brew bundle install --file=./Brewfile

1. Brewfile-Syntax-Grundlagen — 5 Min.

Das Format ist Ruby-DSL, aber in der Praxis reichen fünf Schlüsselwörter vollständig aus.

# Brewfile
 
# tap — zusätzliches Repository
tap "homebrew/bundle"
tap "homebrew/services"
 
# brew — Formeln (CLI-Tools)
brew "git"
brew "gh"
brew "mise"
 
# Optionale Argumente sind erlaubt
brew "postgresql@16", restart_service: :changed
brew "redis",         start_service: true
 
# cask — GUI-Apps
cask "visual-studio-code"
cask "rectangle"
 
# Mac App Store (erfordert mas-cli)
mas "Xcode", id: 497799835
 
# VS Code-Erweiterungen (ähnliche Syntax wie mas)
vscode "dbaeumer.vscode-eslint"
vscode "esbenp.prettier-vscode"

Kommentare + Abschnittsgliederung

# ─── CLI ──────────────────────────────────────
brew "git"
brew "gh"
 
# ─── GUI ──────────────────────────────────────
cask "visual-studio-code"

Abschnitts-Trennzeichen zahlen sich bei der Pflege enorm aus — Diffs werden nach jedem Commit leicht lesbar.


2. Brewfile aus aktuellem Zustand erzeugen — dump — 3 Min.

Wenn du bereits ein gut eingerichtetes Gerät hast, erfasse den aktuellen Zustand auf einen Schlag.

# Brewfile im aktuellen Verzeichnis erstellen (--force überschreibt)
brew bundle dump --force --describe
 
# --describe fügt jeder Zeile einen #-Kommentar hinzu — Lesbarkeit ↑

Beispielausgabe:

# ./Brewfile (automatisch generiert)
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

Den Dump manuell bereinigen

Ein frischer Dump enthält alles, was aktuell installiert ist — meist auch einiges an Rauschen. Bereinigungsliste:

  1. Nur zu Testzwecken installierte Pakete, die du nicht mehr brauchst → entfernen
  2. Sprach-Laufzeiten → ausklammern, wenn du sie mit mise verwaltest (z. B. node, python@3.x)
  3. Arbeit vs. Privat → in Brewfile.work / Brewfile.personal aufteilen
  4. Abschnittskommentare ergänzen

Zehn Minuten Aufwand jetzt ersparen eine Stunde beim nächsten Setup.


3. Auf einem anderen Gerät anwenden — install — 10–30 Min.

Im Verzeichnis mit deinem Brewfile, auf dem neuen Gerät (oder nach der Bereinigung):

brew bundle install --file=./Brewfile
 
# Oder einen absoluten Pfad verwenden
brew bundle install --file=$HOME/dotfiles/Brewfile
 
# Bereits installierte Elemente werden übersprungen (idempotent)

Der erste Lauf wird von Cask-Downloads dominiert (je ~50–200 MB). Plane 10–30 Minuten ein.

Schritt-für-Schritt-Ansicht — --verbose

brew bundle install --file=./Brewfile --verbose

Nur Fehler — --quiet

brew bundle install --file=./Brewfile --quiet

4. Nicht im Brewfile stehende Pakete entfernen — cleanup — 5 Min.

Um das Brewfile zur einzigen Wahrheitsquelle zu machen, alles entfernen, was darin nicht aufgelistet ist.

# Trockenlauf — sehen, was entfernt würde
brew bundle cleanup --file=./Brewfile
 
# Tatsächlich entfernen — bewusst vorgehen
brew bundle cleanup --file=./Brewfile --force

⚠️ --force deinstalliert sofort. Nur ausführen, nachdem dein Brewfile vollständig bereinigt ist; sonst musst du möglicherweise neu installieren.


5. Aufteilungsstrategie — Arbeit / Persönlich / Experiment

Ein einzelnes monolithisches Brewfile wächst mit der Zeit unkontrolliert an. Nach Kontext aufteilen.

~/dotfiles/
├── Brewfile           # Gemeinsam für alle (CLI-Grundlagen)
├── Brewfile.work      # Nur Arbeit (Slack, Zoom, ...)
├── Brewfile.personal  # Persönlich (Spielstarter, ...)
└── Brewfile.optional  # Gelegentlich verwendet

Alle zusammen anwenden

cd ~/dotfiles
brew bundle install --file=./Brewfile
brew bundle install --file=./Brewfile.work
brew bundle install --file=./Brewfile.personal

Oder über Makefile/Shell-Skript

# ~/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 "✓ Alle Brewfiles angewendet"

6. Versionskontrolle mit Git — 3 Min.

Das Brewfile gehört als zentrale Datei in jedes dotfiles-Repo.

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

Wenn später Pakete hinzugefügt/entfernt werden:

brew bundle dump --force --describe   # aktualisieren
git diff Brewfile                     # Änderungen prüfen
git commit -am "feat: add postgresql + redis"
git push

Auf einem neuen Gerät:

git clone git@github.com:<user>/dotfiles.git ~/dotfiles
cd ~/dotfiles
brew bundle install --file=./Brewfile

7. Automatisierung — brew services + macOS LaunchAgent

Einmal täglich automatisch dumpen, damit der brew-Zustand nicht vom Brewfile abweicht.

~/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

Automatischer Dump täglich um 22:00 Uhr. git diff zeigt jeden Morgen, was sich über Nacht geändert hat.


8. Problembehandlung

„Error: Cask 'X' is not installed" (während cleanup)

Der Cask wurde bereits anderweitig entfernt. brew bundle cleanup --force erneut ausführen, um zu synchronisieren.

Dump erfasst zu viele unbeabsichtigte Pakete

Alte transitive Abhängigkeiten werden als Top-Level-Pakete angezeigt. Aufräumen:

brew autoremove   # Blatt-Pakete entfernen, die nur als Deps verwendet werden
brew bundle dump --force --describe  # erneut dumpen

App-Store-Apps erscheinen nicht im Dump

mas-cli fehlt. brew install mas und erneut dumpen.

Einige Casks schlagen beim Installieren SHA-256 fehl

Passiert kurz nach Homebrew-Updates der Cask-Definitionen. brew update und erneut versuchen.


Nächste Schritte

Referenzen

Changelog

  • 2026-05-12 — Erster Entwurf (devAlice M2 Seed-Erweiterung)