Cross-platform dotfiles using chezmoi

Status: Completed
Tech Stack:
chezmoigo/template

Overview

A complete dotfile management solution using chezmoi that enables seamless configuration synchronization across multiple machines and operating systems. Supports templating for machine-specific configurations, encrypted secrets, and one-command environment setup.

Problem

Managing configuration files across multiple machines is challenging:

  • Manual synchronization is error-prone and time-consuming
  • Platform differences (Windows/Linux/macOS) require different configurations
  • Secrets management in dotfiles poses security risks
  • Machine-specific settings make simple Git repos inadequate
  • Setup time for new machines is lengthy and tedious

Solution

chezmoi provides a declarative approach to dotfile management:

  • Version-controlled configurations with Git
  • Template-based configs for cross-platform compatibility
  • Encrypted secret storage
  • Machine-specific customizations
  • Idempotent apply operations
  • One-command bootstrap process

Key Features

Cross-Platform Support

  • Automatically detects OS and architecture
  • Platform-specific templates (.tmpl files)
  • Conditional includes based on system properties
  • Path handling for Windows vs Unix systems

Template System

  • Go template syntax for dynamic configurations
  • Variables for hostname, OS, architecture
  • Custom data files for per-machine settings
  • Conditional logic for environment-specific configs

Secret Management

  • Encrypted files using age or gpg
  • Secure password manager integration
  • Environment variable substitution
  • Automatic decryption on apply

State Management

  • Tracks what files are managed
  • Detects external modifications
  • Interactive merge for conflicts
  • Rollback capabilities

Architecture / Stack

Core Tool: chezmoi (written in Go)

Configuration Structure:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
~/.local/share/chezmoi/
├── .chezmoi.toml.tmpl          # Main config with machine data
├── dot_gitconfig.tmpl          # Git configuration
├── dot_config/
│   ├── nvim/
│   │   └── init.lua
│   ├── powershell/
│   │   └── profile.ps1.tmpl
│   └── starship.toml
├── private_dot_ssh/
│   └── encrypted_config        # Encrypted SSH config
└── run_once_install-packages.sh.tmpl

Managed Configurations:

  • Shell configs (bash, zsh, PowerShell)
  • Editor settings (Neovim, VS Code)
  • Terminal emulator configs
  • Git configuration
  • SSH keys and config
  • Development tool configs (Node, Python, Go)

Implementation Details

Template Examples

OS-specific paths:

1
2
3
4
5
{{- if eq .chezmoi.os "windows" }}
set-alias vim "C:\\Program Files\\Neovim\\bin\\nvim.exe"
{{- else }}
alias vim=nvim
{{- end }}

Machine-specific configs:

1
2
3
4
5
6
[user]
    name = {{ .name | quote }}
    email = {{ .email | quote }}
{{- if .work }}
    signingkey = {{ .work_gpg_key }}
{{- end }}

Bootstrap Process

  1. One-line install:

    1
    
    sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply <github-username>
    
  2. Machine-specific data collected interactively

  3. Templates applied based on OS/architecture

  4. Secrets decrypted with password/key

  5. Scripts executed for package installation

  6. Configurations symlinked to home directory

What I Learned

  • Templating is powerful: Go templates handle complex conditional logic elegantly
  • Secrets should stay encrypted: Never commit plaintext secrets, even in private repos
  • Idempotency matters: Configurations should be reapplied safely without side effects
  • Documentation is crucial: Future you won’t remember the template syntax
  • Start simple: Begin with a few critical configs and expand gradually
  • Test on fresh systems: Bootstrap process should work on clean machines

Benefits Realized

  • Setup time: New machine from bare to fully configured in < 15 minutes
  • Consistency: Identical configurations across work laptop, personal desktop, and cloud VMs
  • Security: SSH keys and API tokens never exposed in Git history
  • Maintenance: Single source of truth for all configurations
  • Experimentation: Easy to test config changes and rollback

Future Enhancements

  • Integration with cloud secret managers (1Password, Bitwarden)
  • Automated configuration testing in containers
  • Machine role profiles (work, personal, server)
  • Configuration generation from UI
  • Team-shared base configurations

Resources