Overview
This guide walks through my automated macOS setup and backup workflow. The goals:
- Quickly set up a new Mac by running a single bootstrap script.
- Avoid manually remembering installed apps, preferences, and configs.
- Automatically back up my dotfiles and Homebrew installs to a GitHub repo.
- Include App Store apps, macOS preferences, and even my AirPrint printer.
Core Components
1. Homebrew Bundle
I use Homebrew’s brew bundle dump
to capture all my brew formulas,
casks, and MAS (Mac App Store) apps into a Brewfile
.
Example Brewfile excerpt:
brew "bat"
brew "zsh"
brew "zsh-autosuggestions"
brew "zsh-syntax-highlighting"
cask "1password"
cask "iterm2"
cask "visual-studio-code"
# Mac App Store apps
mas "Magnet", id: 441258766
mas "AdGuard for Safari", id: 1440147259
mas "1Password for Safari", id: 1569813296
mas "Hush Nag Blocker", id: 1544743900
This file lives in my GitHub repo so it’s always up-to-date.
2. Dotfiles with GNU Stow
I store my dotfiles in version control and use GNU Stow to symlink them into place.
Example directory structure:
~/GitHub Repos/macOS/
├── zsh/.zshrc
├── ssh/config
├── Brewfile
├── bootstrap.sh
└── capture-macos
Stow command used in bootstrap:
stow --adopt -v -t "$HOME" zsh ssh
The --adopt
flag moves any existing local files into the repo so they
are backed up.
3. macOS Preferences
I capture my actual system preferences into a script using defaults
commands so they can be restored later.
Example capture-macos
snippet:
defaults -currentHost write NSGlobalDomain com.apple.mouse.tapBehavior -int 1
defaults write com.apple.dock minimize-to-application -bool 1
defaults write com.apple.dock tilesize -int 81
killall Finder Dock SystemUIServer 2>/dev/null || true
4. Printer Installation
I even automated my printer setup so I don’t have to manually add it.
Example AirPrint addition:
sudo lpadmin -p "EPSON_ET_2760" -E -v "dnssd://EPSON%20ET-2760._ipps._tcp.local./?uuid=cfe92100-6234-1234-a45f-50579ca926aa" -m everywhere && sudo cupsenable "EPSON_ET_2760" && sudo cupsaccept "EPSON_ET_2760" && lpoptions -d "EPSON_ET_2760"
This uses the printer’s UUID so it works even if its IP changes.
The Bootstrap Script
The heart of this setup is bootstrap.sh
.
It:
- Installs everything from the Brewfile (including MAS apps).
- Links dotfiles with Stow.
- Restores macOS preferences.
- Installs my printer.
- Reminds me to do manual steps like enabling 1Password’s SSH agent.
Example excerpt:
#!/usr/bin/env bash
set -euo pipefail
echo "==== Installing packages from Brewfile... ===="
brew bundle --file="$HOME/GitHub Repos/macOS/Brewfile"
echo "==== Linking dotfiles with stow... ===="
stow --adopt -v -t "$HOME" zsh ssh
echo "==== Restoring macOS preferences from prefs/*.plist... ===="
[ -f "$HOME/GitHub Repos/macOS/capture-macos" ] && bash "$HOME/GitHub Repos/macOS/capture-macos"
echo "==== Installing MAS apps (sign into App Store first for success)... ===="
mas install 441258766 || true # Magnet
mas install 1440147259 || true # AdGuard for Safari
mas install 1569813296 || true # 1Password for Safari
mas install 1544743900 || true # Hush
echo "==== Installing printer... ===="
sudo lpadmin -p "EPSON_ET_2760" -E -v "dnssd://EPSON%20ET-2760._ipps._tcp.local./?uuid=cfe92100-67c4-11d4-a45f-50579ca928af" -m everywhere && sudo cupsenable "EPSON_ET_2760" && sudo cupsaccept "EPSON_ET_2760" && lpoptions -d "EPSON_ET_2760"
echo "==== Manual checklist ===="
cat <<EOF
1) App Store: sign in if MAS installs said to wait.
2) 1Password: Settings -> Developer -> enable 'Use 1Password SSH agent'.
3) Safari -> Extensions: Enable 1Password, AdGuard, and Hush.
EOF
echo "==== Bootstrap complete. ===="
Automatic Backups
My .zshrc
runs a daily backup routine:
if [ ! -f "$HOME/.last_backup" ] || [ $(($(date +%s) - $(cat "$HOME/.last_backup"))) -gt 86400 ]; then
"$HOME/GitHub Repos/macOS/bin/backup-now"
date +%s > "$HOME/.last_backup"
fi
The backup-now
script:
- Dumps a fresh Brewfile.
- Copies dotfiles into the repo.
- Commits and pushes to GitHub.
Conclusion
With this setup, I can unbox a new Mac, sign into iCloud and GitHub, run:
git clone https://github.com/zaclohrenz/macOS.git "$HOME/GitHub Repos/macOS"
cd "$HOME/GitHub Repos/macOS" && ./bootstrap.sh
…and in minutes have my full environment restored — apps, preferences, printer, and all.