Managing dotfiles with GNU Stow and Forgejo
2026-05-14 08:30
Note, I am not a sysadmin professional, so please if you notice wrong terminology or things I am doing wrong, get in touch so I can learn and fix it up. Brandon does a much better write-up of this, which is where I first heard about Stow and committed to use one day.
Since my migration from Windows to Linux a couple of years ago, I have forever been installing and customising tools to suit my needs wants. That is the beauty of Linux for me. It gives me a level of freedom that Windows never gave me. I'm making an assumption there though... I never tinkered in Windows with static site generators, text editors, network monitors, git, etc etc. I imagine it can all be done, but surely all that is easier, and faster, with the use of a Linux terminal emulator and apt package manager? As a tinkerer, Linux is easier, not harder as we were led to believe.
With that said, by tailoring our workflows and digital environments via configuration files and custom scripts, we add complexity. Luckily there are more tools out there to then reduce complexity. It sometimes takes a bit to set up, but once it's all going, it generally looks after itself. Git for version control, Syncthing for syncing, BorgBackup for general backups, and here now I'll run through my GNU Stow setup for config file backup and deployment. I am also trialing this with systemd service files and ssh keys.
GNU Stow is a "symlink farm manager". As far as I know, symlinks are essentially like a traditional shortcut where there is a source file stored elsewhere and the symlink just points to it (that is a big simplification). By reading subfolder paths to create symlinks, Stow is a great way to deploy these symlinks for config files and the likes, which can be scattered all over a machine.
Stow is available via apt:
sudo apt install stow
If you have a folder, say ~/dotfiles/ and within there files and folders like .bashrc and .ssh/config, and at the ~/ level your type stow dotfiles, it will create symlinks at ~/.bashrc and ~/.ssh/config respectively, which link back to this dotfiles directory. Then, when you edit say ~/.bashrc, you will be editing the ~/dotfiles/.bashrc file, which is tucked in with all the other files you are stowing.
Turn this ~/dotfiles folder into a remote Git repository, and you've got all your config files at the ready for any machine that can access it. Just clone the repo and start stowing. I've got the repo stored on a Forgejo instance on my Raspberry Pi. It may be more appropriate to store it off-site on Codeberg however.
Rather than stowing the entire ~/dotfiles folder in one go, I like to create individual folders for each package or function. This means I can pick and choose one by one when they are required. Useful for when you use multiple machines for different purposes. My current stow folder looks like this:
zkbro@laptop:~/dotfiles$ tree -L 1
.
├── async-neocities
├── bashrc
├── buku
├── certs
├── helix
├── lagrange
├── librewolf
├── neocities
├── ssh
├── stew
├── syncthing
├── systemd
├── tmuxp
├── tut
└── yazi
As an example, the ssh subfolder has a config file and ssh keys, and looks like:
zkbro@laptop:~/dotfiles/ssh$ tree -a
.
├── .ssh
│ ├── config
│ ├── id_ed25519
│ ├── id_ed25519_borgwarehouse
│ ├── id_ed25519_borgwarehouse.pub
│ ├── id_ed25519_forgejo
│ ├── id_ed25519_forgejo.pub
│ ├── id_ed25519.pub
│ ├── id_rsa
│ ├── id_rsa.pub
│ ├── known_hosts
│ └── known_hosts.old
So, when in ~/dotfiles I type stow ssh, it will create a symlink ~/.ssh/ to that directory:
zkbro@laptop:~$ ls -a | grep ssh
lrwxrwxrwx 1 zkbro zkbro 17 May 14 10:02 .ssh -> dotfiles/ssh/.ssh
Now, like I mentioned earlier, when I edit say ~/.ssh/config, I will actually be editing ~/dotfiles/ssh/.ssh/config, which is regularly backed up in a Forgejo repository. Likewise if I create a new ssh key, because the folder is symlinked, that ssh key will be part of the repo.
I am yet to pull all these into a new system, and I will no doubt hit some problems, especially since I'm trying systemd service files where I always have ownership issues. I have probably missed some important files too, which I'll soon discover, but I'll update the repo as I go.
I've seen others use chezmoi for similar use-cases, but this looks a little advanced for me.
I started this post saying software like this reduces complexity, but I think I was wrong there. I've made my system more complex, but I have simplified the workflow of restoring configuration files.