Up until now, there’s been an unspoken assumption behind every chezmoi init --apply: the age key is present. That means SSH keys get decrypted and placed, the git remote switches to SSH, and everything just works. On a trusted machine — your main workstation, your server — that’s exactly what you want.
Third time’s the charm. tmux has been installed and waiting since the Ansible post, and after two detours through eza, fzf, and zsh plugins, it’s finally getting its configuration. No more excuses.
The goal today: a .tmux.conf that feels right from the first keystroke, plus a plugin manager to handle session persistence — because losing your tmux layout to a reboot is the kind of pain you only tolerate once.
I know, I know — I’ve promised tmux configuration twice now. But when I sat down to work on it, I kept getting distracted by how bare the shell itself felt. No prompt worth looking at, no autocompletion hints, no syntax coloring. Every time I typed a command, the stock zsh experience reminded me there was unfinished business here first.
In the previous post, I wrapped up the installation story. We now have four strategies for getting software onto a fresh machine. But installing tools is only half the job — they need configuring. And eza is the perfect place to start, because it’s a drop-in replacement for something I use hundreds of times a day: ls.
In the previous post, I fixed the onchange script so the Ansible playbook actually triggers when it should. At the end, I mentioned fzf as the next tool to install. Here’s why it needed a different approach.
Three Installation Strategies So Far # Over the last few posts, we’ve built up three ways to install software through chezmoi:
In the previous post, I extended the Ansible playbook to install eza from an external apt repository. Everything worked in the container. Time to run it on my actual WSL2 machine.
chezmoi update Nothing happened. No Ansible output. No errors. The playbook didn’t run at all.
In the previous post, we wired Ansible into chezmoi and installed tmux as our first package. One playbook, one task, one apt install. Clean and simple.
Now I want to add eza — a modern replacement for ls with color-coded output, git awareness, and sensible defaults. It’s one of those tools that, once you’ve used it, makes plain ls feel like staring at a wall of text.
In the previous post, we completed the git setup for our chezmoi repo — identity, SSH key, remote URL, all configured automatically. After running chezmoi init --apply on a fresh machine, the dotfiles land, secrets are decrypted, and you can push immediately. The setup flow works.
In the previous post, we automated the installation of age and zsh with a run_once script. After running chezmoi init --apply on a fresh machine, the right tools are now in place and our SSH keys are decrypted. But there’s a catch — we still can’t push.
In the previous article, we encrypted our SSH keys with age and stored them in the chezmoi repo. That’s great — but there’s a gap. When we set up a new machine and run chezmoi init, chezmoi needs age to decrypt those keys. And as we saw earlier in the series, the version of age available via apt on Debian is too old for post-quantum support.
In the previous article, we spent some time getting a post-quantum enabled version of age installed. Now it’s time to put it to use — by creating an age key and wiring it up with chezmoi to encrypt our SSH keys directly in the dotfiles repo.
In the previous article, I set up disposable containers to test my chezmoi dotfiles. That works, but there’s still too much manual effort involved — especially the SSH key. Every new container means copying it in by hand.
So I decided to encrypt the SSH key with age and store it directly in the dotfiles repo. Chezmoi supports age-based decryption out of the box, which makes this a natural fit. On top of that, I want future tool installations — zsh, tmux, neovim — to be handled automatically too, not typed in manually every time.
In the previous article, we got started with dotfile management and zsh using chezmoi. Now I’d like to experiment — try out new configs, install tools, tweak settings — but without ruining my host’s environment in the process.
A safe space to try things out that also plays perfectly into my later dev container goal: one-time containers. They let me practice spinning up my environment from basically nothing, and they allow me to experiment with apps and configurations without any effect on my host machine. If something breaks, I just exit the container and it’s gone.
Getting Started with Dotfile Management # Up until now, I’ve mostly been working with GUI-driven IDEs on Windows. I wrote about why I’d like to shift to the terminal — the short version is that a portable, keyboard-driven workflow matters when you’re building solo. But alongside that shift, something else has been happening. Since Docker entered my daily work, I’ve been spending more and more time on Linux again — something I hadn’t done seriously since studying computer science. Linux stepped back into my life gradually, and for a long time I just used it without thinking much about it. I never cared about the fundamentals.