The biggest difference between my setup and your setup might be our configuration files. In Unix world we call them dotfiles. Dotfiles are just files whose filename starts with a dot and will be hidden by default in our file managers.
Usually we have several machines that we use consequently, and we want all those machines to share the same environment. And that’s why most most people will have have own collection of dotfiles stored somewhere so they can easily migrate them over to their new machine.
This could be easily achieved without having any software, you can just store them in your Github repository right? Right, but not everything will go as you want it to be. Here’s my take on what problem you might encounter:
- Sometimes you have different versions of programs that needs changes in the dotfiles
- You don’t want your secrets like credentials etc in a git repository unencrypted
- You need to do something on your brand new computers before you can use those dotfiles
- The path where those dotfiles should be are different across machines
You may have more problem than I can think of right now. But in my experience, chezmoi covers everything. Please note that this is not a step by step tutorial on how to use chezmoi because it’s a very complex program and you’ll need a lot of readings. You can start from the easy to follow official documentation to get started. This post is more about me sharing how I’m managing my dotfiles with chezmoi.
I have been using Linux as my primary OS since 2012. And I had my first dotfile was like a year after using Linux when I switched to use ZSH as my default shell. I don’t remember how I managed them back then, but from my dotfiles repository timeline I first created that repo in June 2014. I started out by symlinking my dotfiles from git repository into my
$HOME directory, to having an install script written in bash, to having ansible-playbook, to using chezmoi.
From my experience all this years, I can feel how much chezmoi helped me in managing my dotfiles, and I want to share it.
The first thing you need to do before starting to use chezmoi is of course installing the program itself. There are a lot of ways to install chezmoi, but I like the put them in a script. So I can just run one command like this to install chezmoi:
curl https://raw.githubusercontent.com/budimanjojo/dotfiles/master/install.sh | bash
Once installed, you can create a repository in Github or Gitlab or any other similar tools to host your git repository. To simplify using chezmoi, I suggest you to name your repository
dotfiles. Once done, you can run
chezmoi init <your remote repository username> and you can start adding your dotfiles with
chezmoi add command.
Understanding the Concept
Chezmoi is very different from other dotfiles manager tools out there, it might be confusing at first. Especially if you used to use the traditional ways like symlinking or using stow.
What you need to know is, try to use
chezmoi command as much as you can. For example, to add your Alacritty config, you do
chezmoi add ~/.config/alacritty/alacritty.yml. This will create the file in your repository with this path:
dot_config/alacritty/alacritty.yml. You can then do git add, commit, and push the changes to your remote repository. On your other machine, you can then install and init chezmoi, then do
chezmoi apply to copy your Alacritty config into your new machine.
In summary, you do
chezmoi init command once, then add files into your repository with
chezmoi add. Once you have everything added, in your new machine you simply do
chezmoi apply and everything will be applied to your new machine. Also, there is
chezmoi update command to update your local repository to match your remote repository. I suggest you to setup chezmoi completion for your favorite shell so you can start managing dotfiles with chezmoi be easier.
What Is the Difference From Other Tools
I can see you guys might be asking what is the difference from other tools. You can look at this comparison table. For me, chezmoi have everything you may or may not have. It’s like combination of all the other dotfiles managers out there that do everything. Here are the features that I’m currently using intensively.
This is by far one of the features that I love so much when using chezmoi. To add a template in chezmoi, you can use
--template flag when doing the
add command like this:
chezmoi add --template ~/.gitconfig. This command will create a
dot_gitconfig.tmpl file in your repo that you can start templating. What’s the use case of this? A lot, I mean really a lot. You can use it to change a value of a dotfile according to hostname, OS, etc.
When you do chezmoi init, it will create a set of variables that you can use. You can look at them by doing
chezmoi data command, it’s similar to what
ansible facts is. You can also add your own “data” using chezmoi config file.
I use template for things machine specific config, for example I want my terminal font to be size 12 in my main machine, but I want it to be size 14 in my work machine. I also use it to disable something when it doesn’t match some conditions, for example I want to load
kubectl command completion when I’m at my work machine but not on my home machine.
2. Ignore File
You can also add a file named
.chezmoiignore in your repository and chezmoi will ignore the files listed inside. It’s like
.gitignore file, but the patterns you put inside should match the
source file and not the
destination file. Usually you put your
LICENSE in here so they don’t get into your
$HOME directory. But the great thing about this file is you can also do templating inside it. I use this to ignore files base on conditions, for example I ignore window manager specific dotfiles when the machine is headless etc.
Now this is another powerful feature from chezmoi, scripting. You can add scripts anywhere in your repository or put them in
.chezmoiscripts directory. The filename has to starts with
run_ and ends with
.tmpl. Basically these scripts will run everytime you do
chezmoi apply command, but you can tell it to run once per machine or only run when there are changes. You can also specify whether the scripts should be run before or after copying the dotfiles. For example, to have the script run once before updating the dotfiles, create the filename like this:
There’s one thing you need to be aware of, chezmoi will run these scripts using
exec command. So you need to make sure you provide
shebang inside the file. Also, try to make those scripts as idempotent as you can so it doesn’t do the same thing over and over again whenever you run
I use this feature to do packages installation, setting up shell, downloading something, etc.
4. Encrypted Secrets
Another feature of chezmoi is the ability to put encrypted dotfiles in your public repository safely. Chezmoi supports whole file encryption using age or value encryption using password managers. I don’t use password manager yet so I can’t say much about this. But I use the whole file encryption with age and it works fine. If you want to have a glimpse on what age is, I have a post about how I use SOPS and age to encrypt my kubernetes secrets.
To actually create encrypted dotfile using age with chezmoi, you need to have this section in your chezmoi config file:
encryption: age age: identity: <path to file with your age private key> recipient: <string of your age public key>
Then you can simply do
chezmoi add --encrypted <filepath> to create an encrypted file in your repository. Chezmoi will decrypt the file on your other machine before applying them using the same age private key. You might want to have age private key inside your new machine first.
I think this should wrap all the things I want to share about chezmoi. It’s so much more you can do with chezmoi but I really don’t want this blogpost to be any longer. And this is how I’m managing dotfiles with chezmoi. Feel free to leave some comments if you have any suggestion or question. Also check out my dotfiles repository if you want to look at how I implement chezmoi.