Dotfiles at scale

a big crowd walking in the same direction Like everyone, I now store configuration files and customizations for my beloved shell environment in a git repository.

Why ?

I have to admit, I'm no minimalist when it comes to computers. Without counting my work-provided laptop, I use two laptops, one desktop, a few servers and that's without mentioning what's in the cloud, or the gadgets (e.g. PineBook and Raspberry Pi) . Each and every one of these systems run a Unix-based operating system, either GNU/Linux, macOS or NetBSD.

What these operating systems have in common is a command-line interface, or a shell. And with time, I learned to tweak it and add a lot of small tools that helps me in my various actions.

Multiple systems, but same configuration. You know where I'm getting, don´t you ? Why would I do it by hand ?

How ?

The first reflex when it comes to quickly give several systems the same configuration is to copy the same file on each of them. Then, I figured I could pull the file to a central location, and push new versions to that location. That reasoning leads to one key concept everyone already guessed : version control system. So yes, I created a git repository. I even ended up renaming it to the same as everyone else : dotfiles.

Challenges ?

That kind of setup brings 3 challenges. The first one is how to organize the files in the repository ? To me, the easiest way is to create a directory for each tool, and give the configuration files the same names they would have in their target system. Quick example : in my repository, my VIM configuration file is vim/.vimrc, and it will be used in ~/.vimrc.

The second challenge is how to install the files ? I though about copying them from the repository, but it means I have to run an "install" phase each time I update my repository. I decided to opt for symbolic links. That way, I don't have to run an "install" phase for each update, just for the initial set up. One major advantage I also find is that I can modify the files straight from their supposed location. I can then spot the differences, and be reminded to commit them if I git pull -r after that.

The third challenge is automation. I don't want to have to manually copy the files (or in my case, symlink them). I know some people make heavy use of Ansible even to set up their desktop environment. I'm not there. Yet. To me, starting with installing Ansible is not lightweight, so for now I decided to stick with a good old Makefile. I declared an install target, which creates the symbolic links, a pkgin-deps target for installing useful softwares (on NetBSD and macOS), and finally rpm-deps for installing the same softwares (and more) on Fedora, my distribution of choice.

What's next ?

This seems already complete, but as it turns out, there are more challenges to overcome :

  • I may use another Linux distro (Alpine, Debian, and sometimes even Ubuntu) ;
  • some commands do not behave the same depending on the operating system : my latest issue is with which, which does not have some GNU options on NetBSD ;
  • I would like to also configure some graphical parts of the desktop : I'll be soon digging in the commands to configure Gnome and macOS !

I hope you enjoyed this post ! If you did, please share it on your favorite social networks :-)

Photo by Rob Curran on Unsplash.