61 comments

[ 68.5 ms ] story [ 1093 ms ] thread
Somewhat odd to claim managing dotfiles securely and then tell people to execute 350 lines of shell script to install it.
Security is in the eyes of the beholder. I was trying to find the actual program. All i found was only instructions how to install it.
Somewhat disingenuous to boil it down to this, when it's merely one of the ways presented with 4 other ways of installing it, including downloading the binary, package managers, building from source...

Looking at said install script it's also pretty much just figuring out the host OS and architecture, downloading the corresponding binary, checking its integrity and copying it in place.

It's the first thing after the elevator pitch intro.

I didn't even notice the install link (which is in a menu on the side) and the text didn't indicate another installation option.

I just use Ansible for this purpose.

All my work machines are set up using a single, parameterized Ansible playbook.

Clever, I'll have to look into that. I thought this was a no-brainer and that this was something everyone did some way or another. I use github for my dotfiles, also, try to keep them synchronized on my mac/pc/linux for familiarity. very simple stuff though. Also easy to pack and transport in cases where I cannot directly connect to internet.
Can you share it?
Unfortunately, I can't share it "as is", as it has grown a lot over the years and contains a lot of information about my home and work network topology and setups. (I host it on a private git server)

I copied some of it into an example repository to showcase the structure and left the playbook.yaml intact for reference. You can find it on: https://github.com/cybrox/ansible-setup-example

I don't want to claim that this structure is in any way better or worse than anything else, it's just one that works for me. There's a lot of discussion on how Ansible projects should be structured. This allows me to simply run `WORKSTATION=home DESKTOP=wayland ansible-playbook playbook.yaml` on a fresh Arch Linux install and everything is ready to go.

For maintaining the repository, I got used to changing things in there and deploying them instead of changing dotfiles directly. However, I do also deploy a bash script to copy all the files from the system back to the repo to catch dotfile edits I did hastily at 3am.

An example of dotfiles being deployed with this approach is roles/shell/tasks/zsh.yaml

Oh, if you wouldn't mind sharing, that would be greatly appreciated! For set up of my machine(s), I was going to go the route of using a bash or python script...but when i learned (a high level summary) of ansible, figured that might be a skill that i can leverage for work in the future too. So, I'm trying to play, learn about ansible. (I already have basics of python, so ansible was an add-on for me.) The more that i can learn from examples of others, the better i can learn what are good practices, etc. Thanks!
I've shared an example based on what I currently use here: https://news.ycombinator.com/item?id=32639329 :)

I used to use bash scripts myself, however, I did transition to Ansible because I often ran into problems with replayability of scripts (running them multiple times).

Ansible (and other tools like it) handle stuff like "change a line in this config file to that" or "add this flag here when xyz" easily and you can run it as many times as you like.

Also, Ansible Galaxy offers a lot of roles ready-to-use such as docker setup or asdf version manager plugin management. Though a lot of it is often not that well maintained.

Avoiding Ansible is precisely why I use chezmoi.

Unfortunately I still have to use Ansible for stuff that isn't my dotfiles, but the less Ansible, the better. It feels like whatever use cases I have for Ansible are weird and not what other people are doing, because everything I try to do is difficult and poorly documented. For example, when I try to spin up a machine running Alpine Linux using Ansible, I've encountered all sorts of strange bugs, some of which I've reported and are (being) fixed, but it boggles my mind that what I thought would be really basic stuff, like setting the hostname or the timezone, is buggy as heck.

(comment deleted)
I use Nix [1] (package manager) to handle my configurations over different systems. There is a somewhat steep learning curve, but it is perfect for my use-cases.

[1]: https://nixos.org

yes same, took me too much time to reap the benefits of nix and home-manager but provisioning the new laptop from my configs was such a breeze
Would that work across Linux/macOS/Windows? Thought Nix was generally for Linux, and usable with caveats on macOS, but no Windows support.

Main selling point of Chezmoi seems to be the "multiple diverse machines" part, which would mean multiple OSes and at least Linux/macOS/Windows.

I use it on Linux and macOS machines. I am afraid there is no support for Windows.
I started using this recently and it’s working pretty well. It’s just a porcelain around having a git repo for your home directory files (there’s one level of indirection though where files are copied to/from the repo and your actual home dir).

Previously I used symlinks to dotfiles in Dropbox but I find git a better match for dotfiles.

True, but there's templating with variables and conditionals too. Useful for differentiating between environments, for example work Mac and home WSL2.
Gave it a try a few months ago and realized I can't stomach its approach of copying everything into its own folder and editing your configs over there.

I'd rather tell the tool to watch for changes in my local files. Yes, most of them are in .config, so no big change, but still...

Matter of habbit I guess.

I felt the same way and pared down the workflow. I edit my files directly. Then when done, I do a single `chezmoi add`, which pushes it to the git repo because I have auto commit/push enabled in ~/.config/chezmoi/chezmoi.toml

    [git]
      autoCommit = true
      autoPush = true
Yes but this can be just a very simple (z\ba\fi)sh function. What's the point of keeping yet another tool for this?)
I agree that if you don't need additional chezmoi features you can easily implement the git commit and push in bash to avoid the need to bootstrap by downloading the chezmoi binary. I hope to take advantage of some of the additional chezmoi features in the future.
I just use a boring python-script for this job, which links everything from my repo to the correct location. This has the benefit that I can also add some personal tweak to some configs, like linking my userchrome from Firefox to my profile.

Similar solution for packages and other settings, just a bunch of shell script doing stuff. I tried using Ansible in the past, but maintaining a rarely used tool with many updates was too much of a hassle. At the end, the simple solution is the best one, for me.

I doubt the scripts are simple, it’s not easy to make such things idempotent.
Depends on your definition of simple. There is not that much which can go wrong.
idempotent is about the most useless word ever.

When all the words are sitting around at the end of the day, you got a few good ones making dinner, and maybe a clever contraction sitting on the couch, then you have little Idempotent, chewing on a fucking crayon in the corner with a finger in the light socket.

I’m not sure what you’re getting at. Idempotent has a very clear definition.
Hmmz so with Chezmoi you can't edit your files directly... not very convenient. I'd rather use a bare Git repository :

- https://www.atlassian.com/git/tutorials/dotfiles

- https://www.ackama.com/what-we-think/the-best-way-to-store-y...

You can edit them directly, you just have to "re-add" them so that chezmoi is aware of the change. Kinda like how you have to git add the files in a basic git repository.
That's why I use https://yadm.io

It's basically a helper for a bare git repository plus some added features.

Thanks for the tip, looks interesting. Will check it out;

I'm still in doubt though, as git will work forever, "without" bugs, and be supported on any OS :-)

I edit my Chezmoi files directly. You can run `chezmoi diff` to see the differences between the Git state and what's actually on disk. I manually apply the changes that I want to keep, and then `git commit` + `chezmoi apply`
Chezmoi has some interesting features, that go beyond simply managing dot-files in a Git-repo, that allows it too deepen in a way that makes it quite capable:

- templating for any configuration file built-in

- support for password managers

- can download and unpack an archive, or clone a repo, and refresh it e.g. once a week

- run scripts when applying config changes (either once, or every time)

- can handle config files that are externally modified

- can keep the source dotfiles encrypted on disk, and only unlock them when applying changes to the local generated files

In my usage so far Chezmoi has replaced and is now responsible for:

- Vim plugins

- ZSH plugins

- Generate SSH and GPG keys per context when a new machine is set up

- Git configuration (with per-machine and per context GPG and SSH keys)

- Install software on FreeBSD/Linux/MacOS that I need, both from source and/or package managers

- Per machine customization (e.g. differences between 4 core and 8 cores, or 1 GB of RAM vs. 48 GB RAM, etc.)

- Per OS customization (e.g. differences between ZSH on Arch vs. MacOS)

- Per host customization (e.g. different Vim configs on workstations vs. servers)

As far as setting up a new machine goes, I install chezmoi and git manually, and then I run `chezmoi init {dotfiles-repo}`, and that takes care of (almost) everything else, for MacOS, FreeBSD, Debian, and Arch Linux, each with the specific customization I need for that specific distro and host, all generated from a single source of configuration files.

Key for me is that all variations of e.g. `.zshrc` is generated from a single `dot_zshrc_tmpl` file.

Chezmoi is a tool that deepens with use, and I am finding more uses for it as I continue to use it.

When symlinks or a bare Git repo becomes unwieldy, perhaps the platform itself has a native solution (nix, home-manager) or there is something else that does all of it (ansible, dhall) and that's cool. In other cases there is Chezmoi, which was easy to learn to use.

... Except getting used to `chezmoi edit ~/.vimrc` to make changes to a config file. That is some hefty muscle memory to overcome.

Honestly, that's quite the list. From the title and even the home page, it looks like yet another dotfiles manager, but it looks like it can replace what I've gotten with half-baked scripts. Integration with password managers is great!
If you're the kind of person to use ansible or equivalent, anything user-specific is most likely a better experience in czm.

You can get away with doing stuff like package installation as well but anything more advanced on system-level and you probably want to keep/introduce configuration management for that.

Between this and the article yesterday [1] I'm really curious what configs everyone has that they really miss when they don't have them. I know people will fight for their vim config, but what other settings do you actually care about?

[1]https://news.ycombinator.com/item?id=32632533

Having fish installed is a big one, and then a bunch of additional binaries and shell functions that are installed in ~/.local/bin. Most notable among those is direnv, which I want on any computer where I have a project directory. After that, it’s mostly little things that happen rarely, like the tmux configuration for those cases when I am spending a lot of time on a remote server.
fish, neovim, alacritty, bat, karabiner, lsd, tmux, skhd, yabai, sketchybar

fish, neovim, tmux, skhd are the most important ones. Can't live without them.

Outside of my zsh config, aliases, etc one of the things I do with it is keep a list of my brew packages (brew leaves > brew.txt) and dump it into the different systems I use.

I have a lot more stuff synced but that's one use case I rarely see mentioned if at all.

I wind up reinstalling or using new laptop/desktops all the time and its very helpful to keep things in sync. I HATE getting off my work laptop that I just spent 8 hours deving on and getting on my personal laptop and missing things. And vice versa.

2 weeks ago someone asked

> Ask HN: Can I see your scripts?[1]

I really like this[2] solution from /u/hoechst,

> Not really a script, but a `.ssh/config` to automatically deploy parts of my local cli environment to every server i connect to (if username and ip/hostname matches my rules).

> On first connect to a server, this sync all the dotfiles i want to a remote host and on subsequent connects, it updates the dotfiles.

> Idk if this is "special", but I haven't seen anyone else do this really and it beats for example ansible playbooks by being dead simple.

    Match Host 192.168.123.*,another-example.org,*.example.com User myusername,myotherusername
       ForwardAgent yes
       PermitLocalCommand yes
       LocalCommand rsync -L --exclude .netrwhist --exclude .git --exclude .config/iterm2/AppSupport/ --exclude .vim/bundle/youcompleteme/ -vRrlptze "ssh -o PermitLocalCommand=no" %d/./.screenrc %d/./.gitignore %d/./.bash_profile %d/./.ssh/git_ed25519.pub %d/./.ssh/authorized_keys %d/./.vimrc %d/./.zshrc %d/./.config/iterm2/ %d/./.vim/ %d/./bin/ %d/./.bash/ %r@%n:/home/%r

[1] https://news.ycombinator.com/item?id=32467957

[2] https://news.ycombinator.com/item?id=32468605

I could see both being really useful. I don't want my full dotfiles available on arbitrary remote servers. But being able to setup a new dev environment by just cloning my dotfiles and linking them back is also invaluable.
Exactly.

I don't think that deploying all my dotfiles to a remote server is smart. But there are a few things that could be deployed that would help with quality of life.

I think this is a great way of doing that.

> Manage your dotfiles across multiple diverse machines, securely.

> $ sh -c "$(curl -fsLS https://chezmoi.io/get)" -- init --apply $GITHUB_USERNAME

That this is even suggested as an installation command means that they might as well strike "securely" from the tagline. For someone interested in security the foul odor that this line emits is enough to make me stop reading.

I don't get the issue here.

This command basically downloads and execute something. Yes, it requires you to trust the author but that's what you always need to do anyway alas you don't read and compile yourself anything you install on your computer.

Or did I miss something ?

Yes, the trust but verify step where you are supposed to check that the script you received is the one you expected.
Two examples of malicious behaviour:

(1) I have the server you're curling-into-bash. I write my server to check if it's piped into sh; if so, I instead pipe malicious statements.

(2) I have the server you're downloading from. I write the binary you're downloading so that it later executes malicious statements.

The "don't curl into sh" is worried about the former.

But, the latter seems a much more practical attack, that reading the script you curl is insufficient to protect you from.

It seems weird to mention (1) without at least mentioning (2).

Why is this discussion always happening when we talk about downloading and executing scripts when otoh, nobody bats an eye when you need to download and execute some binary ?

I'm not saying that you should trust anything coming from anywhere, but you have no other choice than to trust the author of any software you run on your computer.

Even if the Chezmoi's author was a malicious guy, why would he hide something in the installation script when this script literally permanently installs a program on your computer.

I'm more answering the question than agreeing with the answer.

Trust seems like such an arbitrary set of lines in the sand anyway.

Adding a repo to your OS and installing the package? Fine.

Same developer provides an install script? Absolutely not.

You have to trust somebody eventually, whether it be your HW manufacturer, OS developers, packagers, developers, etc. There's a lot of it blindly going on, but a script running as your user? Just can't.

Given that this is supposed to be "secure management", one would expect something fail-safe, not fail-deadly.

It also requires you to trust that the underlying http server/dns record server infrastructure did not change between runs of the command.

> It also requires you to trust that the underlying http server/dns record server infrastructure did not change

And what form of distribution do you propose that is secure against that?

Note also that the URL is HTTPS.

> That this is even suggested as an installation command means that they might as well strike "securely" from the tagline. For someone interested in security the foul odor that this line emits is enough to make me stop reading.

I don't know. I always think this line smacks of paternalism. For instance, plenty of projects suggest for installation something like:

  git clone https://github.com/twpayne/chezmoi/; cd chezmoi; make; sudo make install
Of course, "curl | bash" is not always preferable. Re: security, "curl | bash" may be preferable here given the superuser privileges, or the privileges required by dpkg upon install of a stray deb package. But is the implication one reads the makefile and the source code before installing when one git clones a repo, but doesn't when the instructions say pipe to bash?

I also think many are afraid to admit FOSS packaging security is mostly smoke and mirrors. Sure, it's nice re: trusting a mirror. It's nice for keeping track of packages and dependencies. But its technical security story vs "curl | bash" would seem only marginally better/worse depending on the circumstances.

Because trust is the great problem. "curl | bash" may have a smell, but it's mostly the smell of the sewer we live in.

Another question one might/should ask is -- what is the cross platform alternative? If it's "Build 10 packages for everyone," I'm not sure how happy that will make anyone. Just specifically re: this tool, imagine wanting to use it everywhere, however, you have a Mac dev laptop and your servers are a mix of Linux/FreeBSD. How much easier is it just to say "I trust chezmoi (because I would have had to trust it anyway) and 'curl | bash' is secure enough?"

Do you disassemble and inspect every binary you run on your computer?
(comment deleted)
Old school guy here; there's something about using Github (as opposed to merely git) that just feels wrong. While I get the flipside, might be cool to rifle through somebody elses dotfiles to see how they do things, having your big ol' batch of configs on the "site designed for public consumption" seems weird.

Especially in light of Microsoft et al perhaps not always playing nice here (see, e.g. youtube-dl)

chezmoi can clone from any git repo, you don't have to use GitHub. You can clone from your own hosted repo, GitLab, sourcehut, Codeberg, or anywhere else.
Chezmoi is great. I've used it to manage my dotfiles[0] for many years now. It integrates with my password manager (1Password), so my secrets are stored in something I already use. It uses Go templates which is a good thing to know nowadays since it seems that many tools are using that.

[0]: https://github.com/shepherdjerred/dotfiles