macOS - Golden Gate
Command Line Tools
Xcode signed in to the paid team is needed for Linux Tweaks' iCloud profile
xcode-select --install
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license accept
xcode-select -p
Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
eval "$(/opt/homebrew/bin/brew shellenv)"
brew analytics off
Bash
brew install bash
sudo sh -c "echo /opt/homebrew/bin/bash >> /etc/shells"
chsh -s /opt/homebrew/bin/bash
nano ~/.bash_profile
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\H\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
eval "$(/opt/homebrew/bin/brew shellenv)"
export BASH_SILENCE_DEPRECATION_WARNING=1
export EDITOR="mate -w"
export PATH="/opt/homebrew/opt/node@24/bin:$PATH"
# vendor/bin/sail -> shared devsites container (ScriptKits sail_docker)
export SAIL_DOCKER_BINARY=sail_docker
Hostname
sudo scutil --set ComputerName coder-mac1
sudo scutil --set LocalHostName coder-mac1
sudo scutil --set HostName mac1.sgtcoder.com
Sleep
install_configs sets these: Wake for network access off, TCP keep-alive on, Power Nap off (on AC, Power Nap holds dark wakes open for hours).
sudo pmset -a womp 0 tcpkeepalive 1 powernap 0
With Wake for network access on, the Mac hands its .local name to a Bonjour sleep proxy (an Apple TV or HomePod) while asleep. On wake, with both Ethernet and Wi-Fi on the same network, it hears the proxy answering over Wi-Fi and renames itself ("coder-mac1.local" is already in use… changed to "coder-mac1-2.local"). Set it back with sudo scutil --set LocalHostName coder-mac1.
If the Mac dark-wakes every ~18 seconds while asleep (keyboard backlight flickers), turn off Auto Input Scan in each MSI monitor's menu.
Dropbox
Sign in and let 4_ScriptKits finish syncing. install_configs links ~/Dropbox to ~/Library/CloudStorage/Dropbox.
brew install --cask dropbox
sudo
Passwordless rules for what update and Linux Tweaks run as root (sudo EDITOR=nano visudo, since TextMate cannot save the root-owned temp file):
Defaults timestamp_timeout=5
coder ALL=(root) NOPASSWD: /bin/launchctl bootout *
coder ALL=(root) NOPASSWD: /opt/homebrew/bin/mas
coder ALL=(root) NOPASSWD: /sbin/reboot
coder ALL=(root) NOPASSWD: /usr/bin/xcodebuild -license accept
coder ALL=(root) NOPASSWD: /usr/sbin/softwareupdate
coder ALL=(root) NOPASSWD: /usr/bin/dscacheutil -flushcache
coder ALL=(root) NOPASSWD: /usr/bin/killall -HUP mDNSResponder
coder ALL=(root) NOPASSWD: /usr/bin/mdutil
ScriptKits
## Scripts to /usr/local/bin, then install_configs ##
bash ~/Library/CloudStorage/Dropbox/4_ScriptKits/Coder/sh/install_scripts.sh
## Homebrew formulae and casks (MAC_FORMULAE / MAC_CASKS) ##
install_packages
parallel --will-cite
## Caprine by hand - Homebrew disabled its cask (unsigned, fails Gatekeeper); it updates itself after ##
## https://github.com/sindresorhus/caprine/releases > Caprine-<version>-arm64.dmg, then allow it in Privacy & Security on first launch ##
## FileZilla by hand - Homebrew removed its cask; it updates itself after ##
## https://filezilla-project.org/download.php?show_all=1 > FileZilla_<version>_macos-arm64.app.tar.bz2, open with Keka, move FileZilla.app to Applications ##
## Again now that everything is installed: builds Linux Tweaks ##
install_configs
install_configs sets the macOS defaults (mouse, fonts, Dock, Finder, Mission Control, text substitutions, 24-hour time, ApplePersistence, hidden files), the Dock layout from dock.txt, SmartGit tools and Linux Tweaks.
Linux Tweaks
Replaces Hummingbird, Easy Move+Resize, Rectangle, Sensible Side Buttons and BetterTouchTool: Option-drag move/resize, snap, mouse Back/Forward, Linux shortcuts, Finder Up and Go to Folder buttons, Copy Path, Convert Image/Video submenus, preferred audio devices.
Allow under System Settings > Privacy & Security (the menu bar icon has a link to each):
Accessibility
Screen & System Audio Recording
Full Disk Access
Automation > Finder
Notifications > Linux Tweaks: Desktop + Lock Screen (Time Machine backup results)
Finder Up and Go to Folder buttons: Finder > View > Customize Toolbar. Go to Folder opens the path on the clipboard (a file opens its folder with it selected), or Finder's Go to Folder box if the clipboard has no path.
Network Shares
With Linux Tweaks > Tweaks > Keep network shares mounted on (off by default), Linux Tweaks keeps the fs1 shares mounted under /Volumes - at launch, after wake and on unlock - the same way Finder mounts them, with Finder's saved keychain password and no Connect dialog. Connect once in Finder (Go > Connect to Server, smb://sgtcoder@fs1/Work) and save the password; the first mount asks to allow Linux Tweaks to use it (Always Allow).
The list is shares in Linux Tweaks' settings.json; an added share mounts straight away:
"shares" : [
"smb://sgtcoder@fs1/Backup",
"smb://sgtcoder@fs1/Knowledge",
"smb://sgtcoder@fs1/Media",
"smb://sgtcoder@fs1/Software",
"smb://sgtcoder@fs1/Work"
]
## By hand (asks Linux Tweaks) ##
mount_share Work
mount_share smb://sgtcoder@fs1/Software
unmount_share Work
Menu: App Settings > Network Shares - Mount / Unmount each, and Unmount All (they come back at the next wake or unlock while the tweak is on). Use fs1, not its IP: the keychain password is saved under the name Finder connected with.
Docker (Colima)
docker login dhi.io
## Colima, swarm, core_stack (traefik, mariadb, phpmyadmin) and devsites ##
setup_local_swarm
Set MYSQL_ROOT_PASSWORD in ~/core_stack.yml when the first run asks, then re-run.
Update
## softwareupdate, git_pull, install_packages + Homebrew, App Store (mas), sync_alerts, clean_caches ##
update
Spotlight
install_configs turns off every Search results type except Apps, and indexing on every mounted volume. Spotlight still lists apps (from Launch Services), and Mailspring and Dropbox keep their own search indexes:
sudo mdutil -a -i off
mdutil -s -a
update finds App Store apps by their receipts and asks the App Store for versions with mas lookup, so App Store updates don't need the index (only mas list and mas outdated typed by hand do). With indexing off, Search Privacy exclusions aren't needed.
Time Machine backup volumes refuse mdutil -i off, so Linux Tweaks keeps them unmounted between backups (see Time Machine below).
macOS turns indexing back on for the Data volume at every boot. install_configs installs a boot job (com.sgtcoder.spotlight-off, root) that turns it off again before login, and Linux Tweaks checks at login and removes any index that got started (needs the mdutil rule under sudo above).
clean_caches (and so update) turns indexing back off on any volume where it came back on and removes that index. To clear an old index by hand: sudo mdutil -X /System/Volumes/Data.
Don't unload com.apple.metadata.mds - Spotlight's app list needs it, and macOS restores Apple's services at reboot anyway.
Linux systemd units are stored as .service.txt: macOS types .service as an app, and Dropbox's File Provider indexes them into Spotlight's Apps results. install_coder_services drops the .txt when copying to /etc/systemd/system.
Time Machine
Two destinations: backups to fs1 over the network every 12 hours, and the local drive backed up by hand once a month and kept unplugged, so one copy is always offline. Time Machine's own schedule is off (Manually): every time it checked whether a backup was due, it mounted the encrypted fs1 backup and left it for Spotlight's mdsync to index for hours, and indexing can't be turned off on a backup volume (mdutil -i off is refused). Linux Tweaks runs the backups instead and detaches the backup and the share as soon as each one finishes.
## Backup Frequency: Manually (install_configs sets it) ##
sudo defaults write /Library/Preferences/com.apple.TimeMachine AutoBackup -int 0
sudo defaults delete /Library/Preferences/com.apple.TimeMachine AutoBackupInterval
## Linux Tweaks ##
Keep Time Machine backups unmounted on: on any mount (including the hidden fs1 backup image), unmount backups,
detach the fs1 image and unmount the share - unless a backup is running
or it was mounted from the menu
Back up every 12 hours after login... on: 10 seconds after login or unlock, back up to fs1 if the last fs1
backup is over 12 hours old (locked-screen backups fail)
Time Machine menu last backup, Back Up Now, Browse Backups, Mount / Unmount Backup Drive, Settings
## By hand ##
tm_backup backup ## fs1: back up, then detach the image and unmount the share ##
tm_backup unmount ## unmount and detach everything unless a backup is running ##
tmutil status
Log: ~/Library/Logs/tm_backup.log
Backup results from Linux Tweaks ("Backing up…", "Backup finished") go through Notification Center so they wait on the lock screen if you lock mid-backup; everything else in Linux Tweaks uses its own toast. Allow it from Linux Tweaks > Permissions > Notifications, then in System Settings > Notifications > Linux Tweaks check Desktop and Lock Screen (Notification Center optional).
The local drive is encrypted and locks when unmounted, and Time Machine won't unlock it by itself, so tm_backup unlocks it with its password from the login keychain. Save it once (prompts twice; the ID is the drive's Volume UUID from diskutil info "Time Machine"):
security add-generic-password -U -s <volume-uuid> -a <volume-uuid> -w
Time Machine on fs1
The TimeMachine share on fs1 caps it at 500G (Samba fruit:time machine max size), so macOS sees a 536 GB disk and prunes old backups to fit. Ignore "Disk Not Recommended for Backups": it wants twice the Mac's whole disk, not twice what's used.
Encryption can only be turned on in System Settings - tmutil has no option for it, and an existing unencrypted backup can't be converted, only replaced:
## System Settings > General > Time Machine > + > TimeMachine on "fs1" > Set Up Disk ##
## Encrypt Backup on (save the password - no restore without it), Disk Usage Limit: None (the server caps it) ##
## Connect as Registered User sgtcoder with the fs1 Samba password ##
tmutil destinationinfo
## Expect two: TimeMachine (Network) and Time Machine (Local) ##
hdiutil info | grep -E "image-path|image-encrypted"
## During a backup: coder-mac1.sparsebundle, image-encrypted : TRUE ##
Time Machine keeps the share password in the System keychain, not Finder's. "Couldn't back up... problem with the network username or password" (error 80) means that copy is wrong: remove the destination and add it again with the Samba password.
While it sets up, the image has a temporary dated name and is renamed to coder-mac1.sparsebundle; each run inside it is a dated .inprogress, renamed to .backup when it finishes.
Calendars: Birthdays and Holidays
Apple's Birthdays and Holidays calendars are generated on each Apple device, and calendars subscribed in iCloud are only fetched by Apple's apps, so other calendar apps (Morgen) never see them. Real iCloud calendars instead, kept up to date by the sgtcoder.com server, so no Mac has to be on:
## Birthdays (iCloud): one yearly all-day event per iCloud contact birthday - hourly ##
php artisan icloud-calendar:sync-birthdays
## US Holidays (iCloud): one dated event per holiday, this year + 5, from the us-holidays package - daily ##
php artisan icloud-calendar:sync-holidays
## Peloton (iCloud): the classes on the Peloton schedule - hourly ##
php artisan peloton:sync-schedule
## Same alerts on every upcoming iCloud event - hourly ##
## timed: 30 min before, all-day: 9 AM on the day ##
php artisan icloud-calendar:sync-alerts
## Other accounts: same alerts on upcoming one-off events (repeating meetings keep theirs) - update runs this ##
## timed: 30 min before + at start (Microsoft 365: 30 min, it keeps one), all-day: 9 AM on the day ##
sync_alerts
Morgen ignores alerts saved on events and uses its own per-calendar defaults (the bell next to each calendar), and its all-day reminders can only be set before midnight - so on the Mac set the bell to 30 min + at time of event, and leave all-day to the iPhone's 9 AM alerts. Set the account defaults too (Google calendar settings > Event notifications, Outlook default reminder, iPhone Default Alert Times) so new invites arrive matching.
On the iPhone, untick Apple's own Birthdays (under Other) in Calendar > Calendars so birthdays don't show twice. Google calendars other than the main one only reach the iPhone once ticked at https://calendar.google.com/calendar/syncselect (add ?authuser=<email> for a second account).
Keyboard Fixes
Home/End move within the line, like Linux and Windows.
mkdir -p ~/Library/KeyBindings
nano ~/Library/KeyBindings/DefaultKeyBinding.dict
{
/* Remap Home / End keys */
/* Home Button*/
"\UF729" = "moveToBeginningOfLine:";
/* End Button */
"\UF72B" = "moveToEndOfLine:";
/* Shift + Home Button */
"$\UF729" = "moveToBeginningOfLineAndModifySelection:";
/* Shift + End Button */
"$\UF72B" = "moveToEndOfLineAndModifySelection:";
/* Ctrl + Home Button */
"^\UF729" = "moveToBeginningOfDocument:";
/* Ctrl + End Button */
"^\UF72B" = "moveToEndOfDocument:";
/* Shift + Ctrl + Home Button */
"$^\UF729" = "moveToBeginningOfDocumentAndModifySelection:";
/* Shift + Ctrl + End Button*/
"$^\UF72B" = "moveToEndOfDocumentAndModifySelection:";
/* Cmd + Home Button */
"@\UF729" = "moveToBeginningOfDocument:";
/* Cmd + End Button */
"@\UF72B" = "moveToEndOfDocument:";
/* Shift + Cmd + Home Button */
"$@\UF729" = "moveToBeginningOfDocumentAndModifySelection:";
/* Shift + Cmd + End Button*/
"$@\UF72B" = "moveToEndOfDocumentAndModifySelection:";
}
Terminal Fixes
https://apple.stackexchange.com/questions/16135/remap-home-and-end-to-beginning-and-end-of-line
Terminal > Settings > Profiles > Keyboard: Home sends \033OH, End sends \033OF.
24 Hour Clock on Login
sudo defaults write /Library/Preferences/.GlobalPreferences AppleLocale en_GB
sudo defaults write /var/root/Library/Preferences/.GlobalPreferences AppleLocale en_GB
Status Bar Spacing
## Set ##
defaults -currentHost write -globalDomain NSStatusItemSpacing -int 6
defaults -currentHost write -globalDomain NSStatusItemSelectionPadding -int 12
## Read ##
defaults -currentHost read -globalDomain NSStatusItemSpacing
defaults -currentHost read -globalDomain NSStatusItemSelectionPadding
## Revert ##
defaults -currentHost delete -globalDomain NSStatusItemSpacing
defaults -currentHost delete -globalDomain NSStatusItemSelectionPadding
Disable MSI Drive / Read-only CPAP
https://discussions.apple.com/docs/DOC-7942
https://www.reddit.com/r/Monitors/comments/v08itb/deactivate_osd_on_msi_monitor
diskutil info /Volumes/NO\ NAME
sudo vifs
## Disable MSI Drive ##
UUID=49D00007-FF63-36B9-9D69-6B3BE16866BB none auto noauto
## Read-only CPAP ##
LABEL=CPAP none auto ro
sudo automount -vc
Find and Remove Startup Items
https://www.macworld.com/article/221774/how-to-find-and-remove-mac-startup-items.html
## Agents ##
/Library/LaunchDaemons
/Library/LaunchAgents
~/Library/LaunchAgents
## Leftovers ##
~/Library/Preferences
~/Library/Application Support
~/Library/Containers
~/Library/Group Containers
Cleanup
## Caches, app leftovers, deleted apps in the Open With list, DNS, Spotlight kept off (also runs at the end of update) ##
clean_caches
## Also thin Time Machine local snapshots, verify the startup disk ##
clean_caches --maintenance
sudo find / -name .DS_Store -delete; killall Finder