12 KiB
Migration Guide: Dotbot to Chezmoi
This guide documents the migration from dotbot to chezmoi for managing dotfiles.
Table of Contents
- Why Migrate to Chezmoi?
- Key Differences
- Dotbot to Chezmoi Mapping
- New File Structure
- Migration Steps
- Usage Guide
- Troubleshooting
Why Migrate to Chezmoi?
Chezmoi offers several advantages over dotbot:
- Built-in templating: Use Go templates for dynamic configuration
- Secret management: Native support for password managers (1Password, LastPass, etc.)
- Cross-platform: Better support for managing dotfiles across different OS and machines
- State tracking: Chezmoi tracks what it manages more precisely
- Active development: Regular updates and large community
- No dependencies: Single binary, no Python required
Key Differences
Philosophy
Dotbot:
- Configuration-driven (YAML files)
- Manages symlinks from a source directory
- Plugins extend functionality
Chezmoi:
- Source-state driven
- Copies files to home directory (can also use symlinks)
- Built-in templating for dynamic content
- Manages the entire lifecycle of dotfiles
Directory Structure
Dotbot:
~/.dotfiles/
├── base/ # Files symlinked to ~/.*
├── config/ # Files symlinked to ~/.config/
├── local/ # Scripts and local files
├── install # Installation script
└── install.conf.yaml # Configuration
Chezmoi:
~/.local/share/chezmoi/ # Source directory
├── .chezmoi.yaml.tmpl # Configuration template
├── .chezmoiignore # Files to ignore
├── run_once_*.sh.tmpl # One-time setup scripts
├── run_*.sh.tmpl # Scripts that run on every apply
├── dot_bashrc # Becomes ~/.bashrc
├── dot_config/ # Becomes ~/.config/
└── private_dot_ssh/ # Becomes ~/.ssh/ with 0700
Dotbot to Chezmoi Mapping
1. Link Directives
Dotbot (install.conf.yaml):
- link:
~/.bashrc: base/bashrc
~/.config/fish: config/fish
Chezmoi:
- Files are automatically managed based on their names in the source directory
dot_bashrc→~/.bashrcdot_config/fish/→~/.config/fish/- Use
symlink_prefix for symlinks:symlink_dot_vim→ symlinked~/.vim
2. Create Directives
Dotbot:
- create:
~/.ssh:
mode: 0700
~/.local/bin:
Chezmoi:
- Create a
run_once_after_create-directories.sh.tmplscript - Or use
.chezmoitemplatesfor reusable directory creation - Chezmoi automatically creates parent directories
3. Shell Commands
Dotbot:
- shell:
- git submodule update --init --recursive
- bash local/bin/dfm install all
Chezmoi:
- Use
run_once_*.sh.tmplfor one-time setup scripts - Use
run_*.sh.tmplfor scripts that run every time - Use
run_before_*.shfor scripts that run before applying - Use
run_after_*.shfor scripts that run after applying
4. Clean Directives
Dotbot:
- clean:
~/:
~/.config:
recursive: true
Chezmoi:
- Chezmoi doesn't automatically remove files
- Use
chezmoi unmanagedto see unmanaged files - Manually remove or add to
.chezmoiignore
5. Host-Specific Configuration
Dotbot:
# hosts/air/install.conf.yaml
- link:
~/.config/:
path: hosts/air/config/**
Chezmoi:
- Use templates with conditionals:
{{ if eq .chezmoi.hostname "air" }}
# air-specific content
{{ end }}
- Or use separate files:
dot_config/file.tmplwith hostname checks
6. Dotbot Plugins
dotbot-brew:
- Replace with
run_once_after_install-packages.sh.tmpl - Use
brew bundle install
dotbot-asdf:
- Chezmoi doesn't have built-in asdf support
- Use
run_once_after_*.shscripts to install asdf plugins
dotbot-pip/pipx:
- Use
run_once_after_*.shscripts - Or use chezmoi's external management
New File Structure
Configuration Files
.chezmoi.yaml.tmpl
Main configuration file with template support. Defines:
- Source directory
- Data variables (hostname, OS, custom flags)
- Merge strategy
- Template options
- Git options
.chezmoiignore
Files and patterns to ignore when applying dotfiles. Includes:
- Repository management files (.git, .github, etc.)
- Documentation
- Development tools
- Old dotbot configuration
Run Scripts
Scripts follow a naming convention:
run_once_before_*.sh.tmpl: Runs once before applying (prerequisites)run_once_after_*.sh.tmpl: Runs once after applying (installation)run_before_*.sh.tmpl: Runs every time before applyingrun_after_*.sh.tmpl: Runs every time after applyingrun_onchange_*.sh.tmpl: Runs when file content changes
File Naming
Chezmoi uses special prefixes:
dot_: Becomes a dot file (.)private_: Sets permissions to 0600executable_: Makes file executablesymlink_: Creates a symlinkreadonly_: Makes file read-only
Examples:
dot_bashrc→~/.bashrcprivate_dot_ssh/→~/.ssh/(mode 0700)executable_dot_local/bin/script→~/.local/bin/script(executable)
Migration Steps
1. Backup Current Setup
# Backup your current dotfiles
cd ~/.dotfiles
git add -A
git commit -m "Backup before chezmoi migration"
git push
2. Install Chezmoi
# The new install script will do this automatically
sh -c "$(curl -fsLS get.chezmoi.io/lb)" -- init --apply ivuorinen
3. Initialize Chezmoi with Existing Dotfiles
# If you want to test before full migration
chezmoi init --apply ivuorinen
# Or initialize without applying
chezmoi init ivuorinen
4. Restructure Files (Manual Step)
You'll need to rename files to follow chezmoi conventions:
cd ~/.local/share/chezmoi
# Rename base files
mv base/bashrc dot_bashrc
mv base/zshrc dot_zshrc
mv base/tmux.conf dot_tmux.conf
# Move config files
mkdir -p dot_config
mv config/* dot_config/
# Move local/bin files
mkdir -p dot_local/bin
for file in local/bin/*; do
mv "$file" "executable_dot_local/bin/$(basename "$file")"
done
# Move SSH files with proper permissions
mkdir -p private_dot_ssh
mv ssh/* private_dot_ssh/
5. Convert Host-Specific Configurations
For files that differ between hosts, use templates:
# Instead of hosts/air/config/fish/config.fish
# Create: dot_config/fish/config.fish.tmpl
{{ if eq .chezmoi.hostname "air" }}
# air-specific configuration
{{ else if eq .chezmoi.hostname "lakka" }}
# lakka-specific configuration
{{ end }}
6. Test the Migration
# See what changes chezmoi would make
chezmoi diff
# Apply changes
chezmoi apply
# Verify everything works
chezmoi verify
7. Clean Up Old Files
# Remove dotbot directories (after confirming everything works)
cd ~/.local/share/chezmoi
rm -rf tools/dotbot tools/dotbot-*
rm install.conf.yaml
rm -rf hosts/ # If fully migrated to templates
Usage Guide
Basic Commands
# Initialize chezmoi with your dotfiles
chezmoi init ivuorinen
# See what changes would be made
chezmoi diff
# Apply dotfiles
chezmoi apply
# Apply with verbose output
chezmoi apply -v
# Edit a file managed by chezmoi
chezmoi edit ~/.bashrc
# Add a new file to chezmoi
chezmoi add ~/.newfile
# Update dotfiles from source
chezmoi update
# See what files are managed
chezmoi managed
# See what files are unmanaged
chezmoi unmanaged
# Re-run scripts
chezmoi apply --force
# Check for issues
chezmoi doctor
Working with Templates
# Execute a template
chezmoi execute-template "{{ .chezmoi.hostname }}"
# See the data available in templates
chezmoi data
# Edit template data
chezmoi edit-config
Managing Secrets
# Use with 1Password
chezmoi secret keychain
# Template with 1Password
{{ (index (onepasswordDocument "my-secret") 0).content }}
# Use with environment variables
{{ .Env.MY_SECRET }}
Updating Dotfiles
# Edit source file
chezmoi edit ~/.bashrc
# Or edit directly and add
vi ~/.bashrc
chezmoi add ~/.bashrc
# Commit changes
cd $(chezmoi source-path)
git add -A
git commit -m "Update bashrc"
git push
# On another machine
chezmoi update
Troubleshooting
Common Issues
1. File Permissions
Problem: Files have wrong permissions after applying.
Solution: Use prefixes:
# For 0600 permissions
chezmoi add --template private_dot_ssh/config
# For 0700 directories
mkdir -p private_dot_ssh
2. Symlinks Not Working
Problem: Chezmoi copies files instead of symlinking.
Solution: Use symlink_ prefix:
chezmoi add --symlink ~/.vim
# This creates symlink_dot_vim in the source directory
3. Templates Not Rendering
Problem: Template syntax is showing literally in files.
Solution:
- Ensure file has
.tmplextension - Check template syntax
- Verify data with
chezmoi data
4. Scripts Not Running
Problem: run_once_ scripts not executing.
Solution:
- Check script permissions:
chmod +x run_once_*.sh.tmpl - Run with force:
chezmoi apply --force - Check script order (before/after)
5. Host-Specific Files Not Applying
Problem: Wrong host configuration applied.
Solution:
- Check hostname:
chezmoi data | grep hostname - Verify template conditionals
- Use
.chezmoiignorefor host-specific exclusions
Debugging
# Verbose output
chezmoi apply -v
# Very verbose output
chezmoi apply -vv
# Dry run to see what would happen
chezmoi apply --dry-run -v
# Check configuration
chezmoi doctor
# Verify state
chezmoi verify
# See source directory
chezmoi source-path
# See what would be applied to a specific file
chezmoi cat ~/.bashrc
Migration Checklist
- Backup current dotfiles
- Install chezmoi
- Create
.chezmoi.yaml.tmpl - Create
.chezmoiignore - Rename files with proper prefixes
- Convert host-specific configs to templates
- Create
run_once_beforescripts - Create
run_once_afterscripts - Test with
chezmoi diff - Apply with
chezmoi apply - Verify everything works
- Update documentation
- Clean up old dotbot files
- Update README.md
- Test on another machine
Additional Resources
- Chezmoi Documentation
- Chezmoi Quick Start
- Chezmoi User Guide
- Chezmoi Template Reference
- Example Dotfiles Using Chezmoi
Notes
What Stays the Same
- Your actual dotfile contents
- Directory structure in home directory
- Git workflow for managing dotfiles
- The
dfmscript functionality (wrapped in run_once scripts)
What Changes
- Installation method (new
installscript) - Source directory location (
~/.local/share/chezmoiby default) - Configuration method (templates instead of YAML)
- File naming (special prefixes)
- No more symlinks by default (unless specified)
Benefits of Migration
- Simplicity: Single binary, no dependencies
- Templating: Dynamic content based on hostname, OS, etc.
- Secrets: Built-in support for password managers
- State Management: Better tracking of what's managed
- Cross-platform: Excellent support for different OSes
- Documentation: Extensive docs and examples
- Community: Active development and support
Post-Migration
After successful migration:
- Update your README to reflect chezmoi usage
- Archive dotbot configuration for reference
- Document any custom scripts or workflows
- Test on all your machines
- Share your experience!