Personal dotfiles managed with chezmoi, supporting workstation, laptop, and server environments. Uses age/SOPS encryption for secrets, Go templates for conditional profiles, and automated post-apply scripts for full system setup.
- Three form factors —
workstation/laptop(GUI, Kubernetes tools, fonts) andserver(minimal CLI); laptops auto-detected via DMI chassis type, workstation/server prompted once at init - Encrypted secrets — age-based encryption with SOPS for API tokens, keys, and sensitive configs
- Catppuccin Mocha theme across all supported applications
- Automated setup — post-apply scripts handle Homebrew bundles, AppImages, Distrobox services, systemd services, NFS mounts, and git repo cloning
- External assets — Catppuccin themes, Bibata cursors, and keyboard layouts fetched via
.chezmoiexternals
- chezmoi ≥ 2.40.0
- Homebrew (Linuxbrew)
- SSH key at
~/.ssh/id_ed25519 - age key at
~/.config/sops/age/chezmoi.txt(for encrypted files, workstation/laptop only)
chezmoi init --apply --ssh auricomYou will be prompted for:
formFactor—workstationorserver(laptops are auto-detected via DMI chassis type and never prompted)
To re-apply after changes:
update-dotfiles
# or manually:
chezmoi applyNote:
formFactordrives a set of derived flags (isServer,isDesktop,isLaptop,isWorkstation) generated into the config's[data]section. If you change the profile, or ifchezmoiwarns that the config template has changed, re-runchezmoi init --data=falseonce to regenerate~/.config/chezmoi/chezmoi.toml.
.
├── .chezmoi.toml.tmpl # Config template (profile, derived flags, age key)
├── .chezmoiignore # Excludes paths per formFactor profile
├── .chezmoiexternals/ # External assets (Catppuccin themes, cursors, keyboard)
├── .chezmoidata/ # Template data (packages, repos, NFS mounts, flavours)
├── .chezmoiscripts/ # Post-apply automation scripts
├── .chezmoitemplates/ # Shared template snippets (script header/footer, externals, palette)
├── dot_config/ # ~/.config — app configurations
│ ├── fish/ # Fish shell (modular conf.d files per tool)
│ ├── git/ # Git config with delta, GPG signing
│ ├── niri/ # Niri compositor (form-factor-aware layout)
│ ├── foot/ # Terminal emulator
│ ├── k9s/ # Kubernetes dashboard (workstation/laptop)
│ ├── atuin/ # Shell history
│ ├── distrobox/ # Declarative Distrobox containers (workstation)
│ ├── rclone/ # Cloud storage (encrypted config fragments)
│ ├── sops/ # age keys (encrypted)
│ ├── systemd/ # User systemd services (workstation/laptop)
│ └── ...
├── dot_local/
│ ├── bin/ # Custom scripts (update-dotfiles, fishfy-path, …)
│ ├── lib/ # Shared shell libraries (chezmoi_utils, common_utils)
│ └── libexec/ # Container/install helpers
├── dot_ssh/ # SSH config
├── dot_talos/ # Talos config (encrypted)
└── Brewfile.tmpl # Homebrew packages rendered from chezmoidata
Package definitions live in .chezmoidata/packages_brew.yaml, .chezmoidata/packages_cask.yaml, .chezmoidata/packages_flatpak.yaml, and .chezmoidata/packages_appimage.yaml. Homebrew and Flatpak packages are rendered into Brewfile.tmpl; AppImages are reconciled through Gear Lever.
| Feature | Workstation | Laptop | Server |
|---|---|---|---|
| Kubernetes tools (flux, helm, k9s, talosctl) | ✓ | ✓ | |
| GUI apps via Flatpak (Zen, Slack, Zed, Steam…) | ✓ | ✓ | |
| Fonts (Nerd Fonts, JetBrains Mono, IBM Plex) | ✓ | ✓ | |
| VSCodium + extensions | ✓ | ✓ | |
| SOPS/age encryption | ✓ | ✓ | |
| Systemd user services | ✓ | ✓ | |
| NFS mounts | ✓ | ✓ | |
| Niri — wider columns & tighter gaps | ✓ | ||
| ZFS rebalance script | ✓ | ||
| Core CLI tools | ✓ | ✓ | ✓ |
Package inventories are intentionally not duplicated in this README to avoid drift. The source of truth lives in .chezmoidata/packages_brew.yaml, .chezmoidata/packages_cask.yaml, .chezmoidata/packages_flatpak.yaml, and .chezmoidata/packages_appimage.yaml.
Scripts in .chezmoiscripts/ run automatically after chezmoi apply:
| Script | Trigger | Description |
|---|---|---|
run_once_after_01_sudo_config.sh |
once | Sudo configuration |
run_once_after_10_system.sh |
once | System setup per profile |
run_once_after_11_udev_rules.sh |
once | udev rules |
run_once_after_13_timesync.sh |
once | systemd-timesyncd ownership/UTC fix |
run_once_after_20_fish.sh |
once | Fish shell setup |
run_once_after_21_atuin.sh |
once | Atuin history sync setup |
run_once_after_27_cursors.sh |
once | Bibata cursor installation |
run_once_after_28_tailscale.sh |
once | Enable/start tailscaled |
run_onchange_after_00_homebrew.sh |
Brewfile change | brew bundle install |
run_onchange_after_01_appimages.sh |
AppImage data change | Reconcile Gear Lever AppImages |
run_onchange_after_12_nfs_mounts.sh |
nfs.yaml change | Configure NFS mounts |
run_onchange_after_22_dms.sh |
theme change | DankMaterialShell theme setup |
run_onchange_after_23_git_repositories.sh |
repos.yaml change | Clone repos & symlinks |
run_onchange_after_24_distrobox.sh |
Distrobox/service change | Create/update declarative Distroboxes |
run_onchange_after_24_systemd.sh |
systemd change | Enable/reload services |
run_onchange_after_25_rclone.sh |
rclone change | Cloud storage mounts |
run_onchange_after_26_bat.sh |
bat theme change | Rebuild syntax theme cache |
run_onchange_after_27_sysexts.sh |
sysexts.yaml change | Install Flatcar system extensions |
Defined in .chezmoidata/repositories.yaml, cloned automatically on workstation and laptop.
Sensitive files use age encryption managed via SOPS. The age key path is configured in .chezmoi.toml.tmpl. Files with the .age extension are encrypted at rest.