Personal dotfiles managed with chezmoi.
- 🔐 Automated SSH & GPG key provisioning from 1Password
- 🎨 Modern shell with Starship prompt, zoxide, ripgrep, delta
- 📦 Homebrew package management with conditional installs
- 🔧 Per-machine configuration via feature flags
- ✅ CI validation of all templates
export NAME="VEBERArnaud-MacBookPro2024" # Choose a name
sudo scutil --set ComputerName "${NAME}"
sudo scutil --set LocalHostName "${NAME}"
sudo scutil --set HostName "${NAME}"# Command Line Developer Tools
/usr/bin/xcode-select --install
# Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# chezmoi
brew install chezmoibrew install --cask 1password-cli
op account add
eval $(op signin)chezmoi init --apply veberarnaudwhich zsh | sudo tee -a /etc/shells
chsh -s $(which zsh)The repository uses a multi-dimensional identity model based on hostname. Each hostname maps to a combination of layers that determine what gets installed and configured.
| Hostname | veberarnaud | emmett | dmc |
|---|---|---|---|
| VEBERArnaud-MacBookPro2023 | ✓ | ||
| VEBERArnaud-MacMini2023 | ✓ | ||
| VEBERArnaud-MacMini2023s | ✓ | ||
| VEBERArnaud-MacMini2026 | ✓ |
veberarnaud— human user (GUI apps, personal tools)emmett— AI agent (headless, no GUI)dmc— DMC orchestrator host (headless, runs agent sessions)
| Hostname | personal | dmc | emmett | vbr_tech | eurosport | mega_lap |
|---|---|---|---|---|---|---|
| VEBERArnaud-MacBookPro2023 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| VEBERArnaud-MacMini2023 | ✓ | ✓ | ✓ | ✓ | ||
| VEBERArnaud-MacMini2023s | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| VEBERArnaud-MacMini2026 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Hostname | elgato | insta360 | scanner |
|---|---|---|---|
| VEBERArnaud-MacMini2023s | ✓ | ✓ | ✓ |
Projects determine which development tools are installed.
| Project | Android | AWS | Consul | Docker | JS | Nomad | Packer | Rust | Swift | Terraform |
|---|---|---|---|---|---|---|---|---|---|---|
| personal | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |||
| dmc | ✓ | ✓ | ||||||||
| emmett | ✓ | |||||||||
| vbr_tech | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
| eurosport | ✓ | ✓ | ✓ | ✓ | ||||||
| mega_lap | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Configuration is defined in home/.chezmoi.toml.tmpl.
.
├── home/ # chezmoi source directory
│ ├── .chezmoi.toml.tmpl # Configuration & feature flags
│ ├── .chezmoiexternal.toml # External dependencies (zprezto, etc.)
│ ├── .chezmoiignore # Files to ignore per environment
│ ├── .chezmoiscripts/ # Scripts run during apply
│ │ ├── system/darwin/ # macOS-specific scripts
│ │ └── run_after_*.sh.tmpl # Post-apply scripts
│ ├── dot_ssh/ # SSH configuration
│ ├── dot_config/ # ~/.config files
│ └── dot_* # Other dotfiles
├── .github/workflows/ # CI validation
└── README.md
| Prefix | Description |
|---|---|
dot_ |
Maps to .filename in home directory |
private_ |
File with 600 permissions |
empty_ |
Creates empty file if not exists |
.tmpl |
Go template, processed by chezmoi |
run_before_ |
Script runs before applying files |
run_after_ |
Script runs after applying files |
run_onchange_ |
Script runs when content changes |
-
Choose a hostname following the pattern
VEBERArnaud-{Model}{Year} -
Add the hostname to
home/.chezmoi.toml.tmpl:{{- if eq .chezmoi.hostname "VEBERArnaud-NewMachine" -}} {{- $project_personal = true -}} {{- end -}} -
Add the hostname to the
$hostsWithSSHKeylist inhome/.chezmoiignore(deploys the SSH key) and inhome/.chezmoiscripts/verify/run_after_verify.sh.tmpl(checks it):{{- $hostsWithSSHKey := list ... "VEBERArnaud-NewMachine" -}} -
Create SSH key in 1Password named
SSHKey VEBERArnaud-NewMachine. To log in from it to the headless hosts, also add it to$clientsinhome/dot_ssh/private_authorized_keys.tmpl, thenchezmoi applyon those hosts -
Run
chezmoi init --apply veberarnaudon the new machine
run_onchange_after_system_ui.sh.tmpl restarts the Mac after a power failure or a freeze and prevents sleep. run_after_remote_access.sh.tmpl enables Remote Login (SSH), checks Screen Sharing, and on the dmc host turns Wi-Fi off (only when wired), FileVault off and enables automatic login (both ask for the account password). It runs on every chezmoi apply but only acts on what is missing, so a failed step is retried on the next apply.
Manual steps, only when the script warns:
~/.ssh/authorized_keys is generated on these hosts from the public keys of the human machines (SSHKey <host> in 1Password, listed in private_authorized_keys.tmpl). The whole file is managed: a key added by hand (ssh-copy-id) is removed on the next apply.
- Remote Login not enabled: add the terminal to System Settings > Privacy & Security > Full Disk Access, reopen it, then
chezmoi apply - Screen Sharing off: System Settings > General > Sharing > Screen Sharing, access for Administrators. It cannot be scripted: a service loaded through
launchctlrefuses connections ("Screen Sharing is not permitted"); if that happens, turn the toggle off and on again - Automatic login refused: FileVault is still decrypting;
chezmoi applyagain oncefdesetup statusreportsFileVault is Off - No display attached: Screen Sharing uses a low-resolution virtual display; an HDMI dummy plug gives a usable resolution
The dmc host runs the DMC instance from ~/.local/share/dmc, started by the launch agent pw.veber.dmc when the session opens, with a daily database backup and log rotation. @dmc-ai/cli is held back from npm update -g and upgraded by hand.
See docs/dmc-host.md: what runs where, day-to-day commands, upgrading DMC, restoring a backup, moving the instance to another host.
Several configuration files support local overrides that are not tracked in git:
| File | Local Override | Purpose |
|---|---|---|
~/.zshrc |
~/.zshrc.local |
Machine-specific shell config |
~/.gitconfig |
~/.gitconfig.local |
Machine-specific git config |
~/.aliases |
~/.aliases.local |
Machine-specific aliases |
~/.ssh/config |
~/.ssh/config.local |
Private SSH hosts |
For active development, symlink chezmoi's source directory to your working copy:
rm -rf ~/.local/share/chezmoi
ln -s /path/to/your/dotfiles ~/.local/share/chezmoiThen use chezmoi apply to apply local changes immediately.
To pull changes from remote:
chezmoi updateMIT