Hacker News new | past | comments | ask | show | jobs | submit login
Chezmoi: manage your dotfiles securely across multiple machines (github.com)
113 points by twp 3 months ago | hide | past | web | favorite | 36 comments

I am a (happy) user of homeshick (https://github.com/andsens/homeshick), but this project really seems to top it by providing the only feature that I've missed until now:

- use the same source file with different results for different machines (eg. .gitconfig for home and office machines)

- option to store secrets in a credentials database and extract them from there (because you wouldn't want to store them in a git repo - even if it's a private one)

I'll definitively give it a try!

(EDIT: formatting)

Homeshick is indeed great, been using it for years. Every time I've compared it to other solutions, it always comes out on top feature-wise. The other solutions are always missing something, like tracking either files and/or entire directories. Tracking whole directories is very important for e.g. storing an entire ~/.emacs.d in git, and tracking individual files is nice so I can just `homeshick track main ~/.config/some-config-file` without tracking all of ~/.config.

> - use the same source file with different results for different machines (eg. .gitconfig for home and office machines)

I do that by storing each machine's copy with its hostname as a suffix and symlinking it into place on each machine. e.g. ~/.config/anacrontab.systemA gets symlinked to ~/.config/anacrontab on systemA, and the repo contains both ~/.config/anacrontab.systemA and ~/.config/anacrontab.systemB. I can even modify one machine's file from the other machine, and it will be updated on the next push/pull.

But having integrated support for this would be nice.

This is a neat git setup for managing dot files:


a slightly bitrotted tool for this https://github.com/RichiH/vcsh

Is there a way to manage different "categories" of systems with chezmoi? For example, a "linux-server" category would contain an essential set of dotfiles, but not all the window manager related stuff from my linux laptop. Looking at the documentation, the only way to do this would be hostname-based templating, but that seems cumbersome as you would have to change every single template to add the new hostname to the section in question.

Yes, you can define your own template variables in the config file, for example if you include:

    category: "linux-server"
in your .config/chezmoi/chezmoi.yaml file, you can then use it in your templates and a .chezmoiignore file (which is also treated as a template). A .chezmoiignore file could look like:

  {{ if eq .category "linux-server" -}}
  {{ end -}}
I use this technique myself: https://github.com/twpayne/dotfiles/blob/master/.chezmoiigno...

Thanks! Just defining it as a config variable is far too obvious in hindsight, I don't know why it didn't cross my mind.

I'll definitely try it out!

I'm using Ansible for that. It has all the promoted features and more. It's made for that, as a configuration management system.


I think this is pretty sweet, but if I were deciding between learning this and Ansible I would choose Ansible

I did this for a while, but then went with a git approach. The problem with dotfiles in Ansible is that you have to write different scripts for different OS', you have to keep testing them e.g. in case a package name has changed. And for me personally, mostly I'm bootstrapping a new version of an OS after a clean re-install, which again can be hard to test (macOS). So for me, Ansible was way too much hassle. YMMV

Although I regularly work on a number of different Linux machines, I've never felt the need for something like this and I suspect mine is not the target use case. But clearly synchronizing dotfiles is a thing people want. So, why? Who is this for? What problem does it solve for you?

For me, the key things are:

- Security. You don't need to store any secrets in your dotfiles repo, and instead delegate secret storage to LastPass or Bitwarden or similar.

- Fine-grained control of small differences across machines, accounts, and operating systems. For example, I want my ~/.zshrc to be roughly the same between my personal macOS laptop and my work Ubuntu server, but I need a few differences between them due to email address, paths to binaries, and OS-specific configuration.

So in this case, you have two machines, and you want each one to have a different configuration -- why not just have a different rc file on each machine and not bother syncing them. Is there a lot of custom dotfile config that you do want to share between them?

I have five machines (personal macOS laptop, work Ubuntu laptop, personal Debian server, work Ubuntu server, personal Raspberry Pi) and yes, there is a lot of custom config that I want to share between them, particularly my git, zsh, vim, and i3 configs.

In my case I have a vimrc file that is now close to .5K lines and keeps getting bigger. I have all my key bindings (skhd) setup in a configuration file, most of these are for my tilling WM (chunkwm) which also needs to be synced accross my work and home environment. Oh yeah don't forget bashrc and config.fish (I have maybe 500 different aliases for commands like git commit -> gm or vim -> v, etc. Small stuff but I still find it extremely useful). Simply being able to lift my hands of one machine and using the next one seemlessly while keeping everything familiar is a pretty neat thing for me, at least productivity-wise.

I, a relative 'nix noob, have been wanting to play around with different distros without losing too much of my configurations in any particuar jump. It seems like this might work for my use.

I use GNU Stow, it's really nice to clone my dotfiles repo, and run an install script to do the symlinks, and then my Vim, ZSH, tmux, git, etc. are all set up the way I like.

OK, but why? Do you do this frequently? I feel like there's a hidden assumption here that I'm just not getting. Do you have a whole ton of machines you log into on a regular basis? Where it's deeply unproductive / impossible to use the default configuration? What gives rise to this state of affairs?

> Do you have a whole ton of machines you log into on a regular basis? Where it's deeply unproductive / impossible to use the default configuration? What gives rise to this state of affairs?

I’m not the parent, but, yeah, this. I don’t have many machines that I need to connect to, but I make sure to sync my dotfiles to each of them. This gives me:

- A different shell prompt on each machine, so I’m less likely to type a command into the wrong one.

- Consistency in my shell aliases, so I never have to see “bash: ll: command not found” again. I have a lot of these, and I’d rather deal with syncing my dotfiles than re-mapping my muscle memory.

- All the helper scripts I’ve written over the last few years, so if I want to write a command and have it available everywhere, all I need to do is put it in a folder and wait for it to be synchronised.

I’ve been doing this for ages so I might be blind to some of the drawbacks, but I really like having the same terminal environment when I have to SSH somewhere else.

I'm very comfortable with my keybindings for a lot of things, particularly the way I have vim and tmux set up to work nicely together. I also have a fairly extensive zsh config using vi mode and some alternate key bindings. If I remote in to a stock machine, I can get by though.

I have about 7 different machines/VMs/VPSes/partitions I use semi-regularly, so it's nice to have the exact same setup I use everywhere.

I also don't want to have to re-create my setup every time because I won't remember all the tweaks I set up months or years ago. I'm not the kind of user who constantly tweaks their configs, I've been using basically the same configs for about three years.

> I'm very comfortable with my keybindings for a lot of things, particularly the way I have vim and tmux set up to work nicely together.

I'm the same way, and I have a similar setup. I have a public git repo with all of my custom git, vim, tmux, etc configs. It serves 2 purposes for me 1. make it easy to setup a new machine (literally run 1 command) and 2. provide a way to automatically backup configs for any machine I am on.

Everything I work on is either in git, dropbox, or I don't care about it. My goal is that I should be able to lose any computer I am working on, and be back up and running within a day.

Huh, I have about the same number. I suppose this is a matter of personal taste. Thanks for addressing my curiosity!

I looked into this and tried porting my dot files over because I was very interested in the templating feature. However, I don't think I'm going to continue because the experience of maintaining these dot files is substantially worse than my current solution. I would be interested in continuing if this feature existed:

I want a command that inspects every file and directory monitored by chezmoi in the target state and updates it in the source state. Specifically:

- New files in tracked directories should be listed with the ability to import them individually (presently you can only do `chezmoi add -r` and deal with the consequences).

- Adding files should respect the `chezmoiignore` file (I never want `chezmoi add -r ~/.config/fish` to import my `fish_history` file).

Thanks for the suggestions, I'll implement them.

In the short term, to chose files individually you can do:

  find ~/.config -type f > file-list
  $EDITOR file-list # remove the ones you don't want imported
  xargs chezmoi add <file-list
EDIT: Issues created: https://github.com/twpayne/chezmoi/issues/123 https://github.com/twpayne/chezmoi/issues/124

Chezmoi looks very cool. I'll definitely give it a try.

Like some of the other commenters here, I use git branches for different setups, though in practice there's only really the one.

I also wrote a shell script (Dotty) [1] to 'collect' and 'deploy' dotfiles mixed freely with shell commands. Mixing shell scripting in lets me do things like remove unwanted files from my .emacs.d/ after collection, preserving nested directory structures, or any other pre- or post-collect/deploy arbitrary actions.

[1] https://github.com/joseph8th/dotfiles

I'm just using a python script and a local copy of some mustache(?) template-library (even using a .tpml extension). Considering flexibility: I guess the configurability of this is offset by having to know Go to extend this (compared to whichever scripting language you are familiar with), Python/Perl probably are available everywhere as well (at least if you don't care for containers). Still it's nice to see some useful approach shown off, instead of all-the-same useless fuss about different branches (which is basically every blog post about dotfile management I found on Google).

Author here. Feel free to ask any questions.

Congrats on the v1.0 release!

Êtes-vous Français?

how's your day going?

stow + git-crypt works well, also. I just added git-crypt two days ago for my very few encrypted dotfiles (cachix key, gist token, etc). Though I understand the desire for it, in reality I've never needed templating for dotfiles, there's always been some other indirection mechanism that was better suited anyway.

`git clone .`, `git-crypt unlock`, `stow --no-folding`, done.

For those who prefer not to learn another configuration management system just for dotfiles but already know salt, here is a masterless salt template for dotfiles: https://github.com/stiletto/salt-dotfiles-template

I feel so dumb, I just started coding a project to sync my configuration files across multiple machines. I even tried a quick "configuration synchronise" search on Github but came up with nothing. Oh well.

Meh, it's a good practice project even if you don't end up using it in the long run. I strongly recommend you follow through with it. Practical real-world problems, like dot-file management and syncing, can lead you to some fun solutions.

I ended up writing my own in Bash about 7 years ago as a way to bring my Bash skills up to snuff. Was well worth it, even if there are good solutions out there. Probably could use some shell hardening and other maintenance, but it works well enough for my use.

I use `rcm` from thoughtbot: https://github.com/thoughtbot/rcm

These suggestions seem like a lot of work.

My home folder is a Git repo and it works great. No complicated setup. Easy to sync remotely and track changes.

I cam across this solution not very long ago: https://news.ycombinator.com/item?id=11070797.

The advantage to Chezmoi (or GNU Stow) is that it can handle things outside of your home directory too (if I understand correctly).

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact