The thing to remember about NixOS is it’s not a distribution of KDE or Gnome or manager of anything, it’s a declarative way of configuring those things and allows you to easily roll back changes to entire OS.
It’s a little bit of investment to get started but one you get rolling it’s such a breath of fresh air to be able to manipulate your whole OS in the similar pragmatic way to you iterate code in a git repo.
That doesn't exactly scream ease of use.
Which is not always up to date, and exposes all the available options. I found myself often need to dig into nixpkgs and add missing options myself during the time I was trying out NixOS.
And believe me, that wasn't a pleasant experience.
I had a similar experience with NixOS and I love it.
I've been trying to do this for ages with a dotfiles repo and some git aliasing. I really want to try it out, though. Any gotchas or hidden pitfalls I should look out for?
If you use nix-env you're just polluting your environment in an imperative way and that is pretty much going against Nix' declarative nature.
Also make sure you allocate enough space on your root partition so you don't have to run garbage collection all the time.
Being able to switch between wildly different possible system configurations like xorg+i3 and wayland+sway by executing a few commands and having version control while doing so is incredible.
However one thing I'm struggling with now is "overlays". Simply trying to get "electrum" to install but nixpkgs has 3.3.8, I am looking to build 4.0.0a from HEAD of master. This should be simple to do with something like overlaying this portion from file electrum/default.nix [0]
src = fetchurl {
url = "https://download.electrum.org/${version}/Electrum-${version}.tar.gz";
sha256 = "1g00cj1pmckd4xis8r032wmraiv3vd3zc803hnyxa2bnhj8z3bg2";
};
with something like: fetchFromGitHub {
owner = "spesmilo";
repo = "electrum";
sha256 = "LATESTHASH";
};
But for the life of me, I can't figure out how to do this overlay stuff. ( In fact I'd appreciate any help on this otherwise at this point I'm even jokingly considering an Arch container :) )Python, NodeJS and Ruby development might also be slightly frustrating if you are used to installing things globally.
[0] https://github.com/NixOS/nixpkgs/blob/master/pkgs/applicatio...
Earlier Nix had additional NixOps but that too now is available with Guix deploy. I am waiting when I can run Guix within a lxd container, shepherd init still has some rough edges with LXD container init.
Both are great piece of software and a new take on building OS and distribution. They are ahead of their time might take another 4-5 years before they become more mainstream.
Of course, none of that speaks to Guix as I haven't used it, but hopefully it's awesome and solves all of those problems.
This gives me hope things are getting better.
Also recently I funded a project for improving error messages in Nix https://opencollective.com/nix-errors-enhancement
Ther is also now a dedicated Nix Marketing team which are working on improving the website and the documentation
I do wonder about the "deliberately cryptic" nature of Nix's expression language. It is, in fact, deliberately designed for simplicity, to be a basic syntax for a language that is purely functional and lazy but not much else ([0] p69). When folks complain about the Nix expression language, as they often do, I ask them: What would you change? How would you do it?
I think that it is bad that an entire team does not have the bandwidth to learn an entirely new language, but good that the team is not willing to spend time on things which they don't think are important.
Not all technologies are good. Not all organisations are good. Sometimes it's one. Sometimes it's the other.
Places that use functional language for their code base don't have problems picking it up. It is especially big in Haskell community, because Haskell is also lazily evaluated.
People might wonder why not use language that more people are familiar? The reason for it is that purely functional and lazily evaluated language is basically behind Nix's biggest strengths. Purely functional means for the same inputs(architecture + source code + dependencies + configuration options + etc) you should get the same output, there's no mutable state the languages always starts the evaluations from a known state.
Why lazily evaluated? That makes the Nix only evaluate things that are necessary to obtain given derivation.
I think when people talk about Nix being confusing they really mean NixPkgs. Which is like a stdlib of Nix. The thing is that Nixpkgs in a constant flux people who work on it work on different components somewhat independently. Also often they realize better ways of doing things, and often the documentation doesn't keep with it. I think that Nix needs some kind of mechanism for literate programming where documentation would live together with the code and would be updated at the same time. There are some effort for example like the NixOS options page is generated from the source, but that's just just small part of Nix and only applies to NixOS.
I also would love if nix would standardize on how to pin nixpkgs. I recently discovered Niv[1] and it makes reproducible builds so much easier. I think Nix also needs some opinionated tooling to create dev environment for each supported languages, currently people need to do it themselves, and it takes a lot of research.
I think Niv + lorri + direnv make dev experience extremely enjoyable. For example a python project set up that way. Once you enter the directory, you have the exact version of Python installed that has all the dependencies (of course with locked versions) and all extra development tooling that developers need with exact same versions. All you need is just run the application and it just works every time. If somebody broke something you can easily use git bisect to find when and why it broke.
Nix fails to document though how a new user get to that point, and desperately needs help there.
Furthermore I do not think you can compare Guix to Nix for commercial work as Nix is LGPL [2] with the packages being MIT [3] where Guix is GPL [4] allowing for Nix derivative work to be used commercially with little restriction.
I wish Guix had stayed as a guile layer for Nix and not gone off in its own direction because of the licensing ambiguity (as far as I can tell this is the reason) in Nix packages. If anyone has more insight on why this split happened or the possibility of making such layers for Nix I'm very interested in this topic.
[0] https://nixos.org/learn.html [1] https://nixos.org/nixos/packages.html?channel=nixos-19.09 [2] https://github.com/NixOS/nix#license [3] https://github.com/NixOS/nixpkgs/blob/master/COPYING [4] https://guix.gnu.org/about/
Linux kernel itself is GPL, so not sure what’s the issue with Guix. Obviously Guix package repository only support libre software, but if you need to use proprietary repository try Guix-nonfree[1].
I am happy Guix and GuixSD exist. Check the gnu Guix mailing list archive both have same roots but are sufficiently different[2].
[1] https://github.com/guix-users/guix-nonfree
[2] https://lists.gnu.org/archive/html/guix-devel/2019-09/msg002...
There is a maintained nonfree Guix channel here if you don't care about such blobs or need other proprietary software: https://gitlab.com/nonguix/nonguix
Rumor has it that Guix will be included in a future Debian release too. It is already available in Arch, Gentoo, and OpenSUSE.
I hear Nix even works on macOS too! :-)
It’s a real shame that rms had such a dislike of Common Lisp. The mind boggles at where the cutting edge of computing would be today had Emacs upgraded from Elisp to Common Lisp twenty or thirty years ago. Instead GNU has spent 27 years trying to turn Scheme into a sufficient systems programming language, once again illustrating the truth of Greenspun’s Tenth Law: Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp. I would add a corollary: this also applies to any sufficiently complicated Scheme program.
https://guix.gnu.org/blog/2020/deprecating-support-for-the-l...
Is it sufficient to run Guix atop another distribution, or run Guix SD in a qemu VM?
[1] https://lists.gnu.org/archive/html/help-guix/2018-10/msg0006...
Nix as a build tool is also quite nice, but honestly NixOS is the main attraction for me.
Check this video out from Rob Vermaas. It's a decent case study of how Nix was applied at LogicBlox
https://github.com/ghuntley/dotfiles-nixos
Steal away and enjoy.
If you want a TL;DR overview of NixOS then start here — https://github.com/ghuntley/workshops/tree/master/nixos-work...
For an advanced example of overriding nixpkg and usage of pinning/override layers (ie some mandate or reason to run super old version of grpc) — https://github.com/digital-asset/daml/blob/master/nix/nixpkg...
Not surprising, given that Nix was a academic research project, and Cardano has a good network of academic researchers working to solve hard blockchain problems.
https://iohk.io/en/blog/posts/2019/02/06/how-we-use-nix-at-i...
Ansible or saltstack are essentially programs that configure your system in specific way. Ansible takes more of a list of things what to change and how, while saltstack tries to be declarative.
NixOS is essentially a Linux system described using Nix language. Whenever you make change and run nixos-rebuild, as name suggests it actually rebuilds your entire system from scratch, it is just smart enough to not do work that was already done.
Benefits of it is that you will always get to the same state no matter what. Another benefit that is quite annoying with saltstack/ansible if you remove specific application/service/whatever once you rebuild the system, it is gone, like it was never there.
You also get Nix benefits, nix never leaves anything in half state changes are atomic, either they are applied successfully or not, if a change broke something, you can easily rollback. Things like for example changing KDE to Gnome or replacing Xorg with Wayland is no harder than replacing emacs with vim (or vim with emacs, if I upset you).
The way how Nix works allows different packages using even conflicting libraries. For example you can have two applications using different openssl version etc.
If you have one application and you need to apply a custom patch to it or maybe even use a different version. In traditional OS good sysadmins would create a custom RPM package an install it. In Nix you just override the definition, and if a cached build is not available, Nix will be smart enough to compile the code (this means no need for artifactory and uploading custom packages there, though to prevent recompiling every time, you should set up a caching server (there's also caching as a service option if you don't want to manage it) or you can even use S3 bucket.
Basically Nix and NixOS is rethinking how building/deploying/packaging does it offers many benefits, CMS like ansible/saltstack/chef/puppet/cfengine etc are no longer needed. It can be used for having comon developement environment, can be used for building, ci/cd etc.
Nixos keeps the entire system state based on a declaration and lets you move back/forward on whole system configurations super quick.
Ansible and salt does not really declare a complete system state but rather try to manipulate the underlying system. Ansible keeps no state at all actually.
Nixos+pkg is all about declaring and keeping a state of a machine as much as reasonably possible. It has it’s flaws but the end result is still much more coherent and predictable compared to traditional configuration management.
you can take any nixos configuration and turn it into a cloud image https://github.com/nix-community/nixos-generators
You can take any nix package and turn it into a docker image https://news.ycombinator.com/item?id=20720922 https://news.ycombinator.com/item?id=18111954
You can even use Nix to create and deploy cloud resources ala Terraform:
github.com/nixos/nixops
Some other notable uses of Nix in cloud native landscape:
https://github.com/saschagrunert/kubernix - a KIND alternative
https://github.com/xtruder/kubenix a Nix DSL for defining and deploying entire kubernetes clusters + deployments (combines nix's docker image building support and deployment support for and end to end cloud-native solution)
I personally think Nix should heavily market itself to the CLoud Native buzzword hype train. as it's my favourite weapon in this space
I think Nix/Nixpkgs/NixOS are great, and by far the best way to package applications. But NixOps, I think, is a mistake - it's an over-extension, the technologies behind Nix are perfect and way better than anything else for package management, but merely OK for host management. I actually think Pulumi has some better ideas for this, so it would be cool to use Pulumi to orchestrate deployment of Nix/NixOS stuff.
What you can do, though, is use Nix to build a container image with an nginx config. You just can't use the abstractions present in NixOS as-is to generate the nginx config, you'd have to write the nginx config yourself (just as you would if you use a Dockerfile). You could perhaps re-use parts, or modify the NixOS modules, though.
If you're interested, you can probably get an invite from @supermario on the elm slack, or on: https://lamdera.app/
Disclaimer: I'm not affiliated with the project, but I've met Mario in person and he's a cool dude with great ideas ;)
Are you objecting to holding all state in a database, or something else? If so, the only real alternative is to have individual servers hold state, which seems like a poor choice; one way or another you're going to hit the CAP theorem, and databases are well-optimized for getting you the best results from CAP that you're going to.