Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Currently I use Ansible to deploy my dotfiles, along with anything else needed to setup a workstation. I keep seeing people mention Nix. Would it give me anything that Ansible and Git can't give me?


I'd describe nix as "programmatic package management". Nix is a difficult tool to learn, but very powerful. A lot of nice UX use cases with Nix could perhaps be described as "like Docker, without the containers".

In terms of applying configs, ansible is 'convergent', where Nix is 'congruent'. https://blog.flyingcircus.io/2016/05/06/thoughts-on-systems-... (ansible will make changes to get it closer to a target state, whereas nix will reach the target state by constructing the target state again).


Thank you. As someone who uses containers a lot (even to run local programs, shout out to https://blog.jessfraz.com/post/docker-containers-on-the-desk...) this makes some sense to me.

I'm a little way into the Nix Pills document (https://nixos.org/guides/nix-pills/why-you-should-give-it-a-...) which seems to start the explanation from a place where I can understand.


X11 is pretty poor for security, you should use Flatpak as it has sandboxing and still stores all its files in one directory.


There is no AnsibleOS, so you'll not have a reproducible OS, and as the base OS gets upgraded underneath, ansible scripts will break. Also, you have to put a ton of effort into making sure Ansible scripts are idempotent, and even then there are usually leaks. Nix (with flakes) is 100% reproducible and it's very difficult to do anything that isn't idempotent. What this all means is that there is more effort up front learning and setting it up, but a lot less effort and suffering in the long term.

I personally switched for these reasons.


Mostly it provides guarantees about your system. It guarantees that anything not in your config is not on your system (for the most part). It guarantees that everything builds successfully before it applies any changes. Most of the filesystem is immutable so it forces you to use the configuration.

There are some other advantages: rollback to a previous state at any time, enable complex system services with one line in your config file, install multiple versions of tools on your system without conflicts, install programs without root (using home manager), build VMs and Docker images, pin the versions and dependencies of all packages for reproducibility, patch software with your own tweaks natively. You can also put a Nix file in a code repo and easily share your build dependencies with other developers.


This might show my ignorance, but can Nix replace something like asdf (https://github.com/asdf-vm/asdf)?


Yes, that’s exactly the kind of thing it’s great at.

Nix stores all builds of its packages in a separate “store” on the machine, each identified by the hash of the build (“derivation”). When you activate your config, it basically symlinks the version you want into your PATH.

If your project needs a specific version, when you activate a Nix shell or script it will check your store for that version and activate it. If it doesn’t exist, it will fetch it (or even compile it from scratch if you need to).


Part of the magic of asdf is that it reads a `.tool-versions` file from anywhere above your current directory and applies the correct version of each tool based on the listed value. (You can also configure a global default version for each tool in case your directory tree doesn't have a .tool-versions file with an entry for the tool you want to use.)

Does Nix allow for a similar workflow? It's really nice to be able to move between projects and automatically have the correct tool versions configured without having to run any special command.


Pretty much. You'd use Direnv to support this UX. https://direnv.net/

I think the nice thing about project-specific tooling like this is it allows getting started with the project very easily. (Rather than copy-pasting "apt-get <whatever>").


To add to what rgoulter said, you can use your default system configuration plus whatever the project says you need (and the project's shell will override any conflicts with your default).

However, if you really want to make sure that you're not including anything from your system, you can have direnv pass the `--pure` flag, which will then include only the dependencies from the project and nothing else. This is helpful to make sure that you're not accidentally relying on something already on your system when you declare the project dependencies.


The biggest advantage that I can give is that everything is together in a unified language. To give a trivial, but extreme example, my workstation's colour scheme is controlled via my Nix setup. This includes terminal colours, GTK theme, Emacs syntax highlighting, Matplotlib colours, CSS overrides, window manager, and more. Yet I can change a single line in my Nix file and update all of these without worrying about the myriad configuration languages that are involved. A single change on a different line will update the default font for all these applications as well.


yep! also what I find nice is you can just ref a package in a config and it just gets installed

e.g. create a g zsh alias for git using the alias section of zsh module in home manager

> g = "${pkgs.git}/bin/git";


Ansible : Nix :: using Javascript to lay out a webpage : using CSS to lay out a webpage


Interrupt Ansible mid way and then change some configs. That's a situation where you probably need to rerun from start and hope for the best. With nix you can just rerun and you would start mid way through your build process without any side effects. Also Ansible cannot easily do iterative changes without rerunning everything or knowing yourself what has changed. With nix the changes get computed and everything that is necessary will rebuild and restart.




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

Search: