NixOS (or Guix) seems like an ideal platform for building service-based architectures. I don't understand why it's not more popular. CoreOS seems to be extremely popular in that space, despite working against a somewhat crappy package manager (portage from Gentoo) and with all of the declarative stuff slapped on top in a quite heavy-handed way. With CoreOS, you roll entirely new images whenever you have a change to deploy. So, the goals are the same, but the mechanisms are so very different as to make them look like they're solving different problems. I'm pretty sure I prefer the way NixOS is going about it.
That said, I've not used either in production. But, Nix was the first time I've looked at a new package manager and thought, "OK, someone finally improved on RPM/yum or deb/apt." Most of the time, I look at new package managers and just find myself running down a list of all of the ways they've failed to even replicate the power/flexibility/reliability of those now-ancient package managers, and usually without any really good reason. It's a cool side effect of a superior package manager that so much other stuff comes easily or automatically.
Anyway, this is a really cool idea, and something I want to look into more. You get so much of the "declarative and predictable" elements you want in a service-based architecture for free with Nix, while so many other solutions are bolted on clumsily.
I use nix in production, and I love it. It's just as good in practice as it is in theory.
I think the problem is that really using nix involves learning a new language. And it's a weird lazy functional language at that. So yeah, the Haskell folk adopt it readily enough, but everyone else has a high barrier to get over. The only people that do it are the ones that have really wrestled with the problem of dependencies and can see how well nix solves it.
That's exactly what I think is so neat about it. puppet, chef, ansible, are all really cool, and they manage to bolt a declarative and atomic looking facade onto something that is decidedly not declarative or atomic (a regular old operating system). But, NixOS hits the problem in the gut. It seems like everything that is hard about the problem disappears when your entire OS is built from the ground up to be declarative and atomic.
It's pretty neat, and once I get my current projects squared away, I want to spend some time with NixOS, and maybe even get involved. It's just such a nice idea, and doesn't make me feel queasy the way so many of the bolted on solutions do.
A minor correction as a courtesy to other readers: puppet, chef, etc are not atomic. They can usually be considered thread safe across processes, if for some reason you run two simultaneously, but that is not a guarantee. Their changes are visible while they are executing on the system, so to other unrelated processes, they are not atomic.
Not so much a correction...I think saying it is "a declarative and atomic looking facade" implies it is not actually that, even though it might look like it, doesn't it? But, perhaps it is a worthwhile clarification.
That's true. And, Apache, the databases, etc. are all challenging. But, one step at a time. NixOS is several steps ahead of what the rest of us are doing (my products run predominantly on CentOS, Ubuntu, Debian, with a small number running on FreeBSD and a few other outliers).
I'm pretty excited about rust based operating system experiments, though it'll probably be 10+ years before we can start using them seriously in production (and operating system kernels have a lot of unpleasant stateful things to deal with, so likely will never be particularly pure no matter what language they're written in).
Anyway, Nix is cool stuff that I think is interesting and novel.
Nothing. It's just a more trustworthy language for building a kernel or other systems software. I was just rambling about cool shit happening in the OS development space.
Yes, I suppose that's one way to look at it. But, to quote from that: "Instead of installing packages via yum or apt, CoreOS uses Linux containers to manage your services at a higher level of abstraction. A single service's code and all dependencies are packaged within a container that can be run on one or many CoreOS machines."
So, you're now managing "containers" instead of "packages". What's the difference in terms of making them reproduce-able and reliable? Very little (though there are big differences in how you deploy them and how they behave when deployed). You still need tools to manage the complexity of reliably building these containers (a "higher level of abstraction" that contains many more moving parts than a single package, generally speaking). They've built configuration management (etcd), and they use existing tools or custom tools for the "packaging" part of the equation (Docker or rkt). Even though they're calling it a "container", you're still building and deploying software...now only with less mature tools than the old ones we've been using for 20 years.
Someone has to build those containers, and someone has to use tools to do so reliably and predictably.
I'm saying that NixOS seems to provide better tools (for both configuration management and for packaging) than the current popular solutions. It surprises me that more people haven't embraced it for doing this stuff. I'm just saying I think NixOS would be an ideal candidate for the same spaces where people are using CoreOS and Docker or CoreOS and rkt.
I think Docker, along with an orchestration system (such as Kubernetes) warrants a try, I was hesitant at first myself. It is just a different way of attacking deployments. It has some overlap with configuration management, but does not cover that entire domain.
As far as reliably building images, I believe you can use Nix to provision images. I don't see this as NixOS vs Docker, I believe they can be used in conjunction.
As far as the maturity, despite its age there is so much momentum behind docker right now. Also, NixOS is also not that old.
I totally understand the hesitation, but I think it's worth trying out.
I think maybe I've mis-communicated somewhere along the way. I'm not saying containers are a bad idea; they're a good deployment strategy for many use cases. What I'm saying is that there are a lot of slapped together tools out there trying to provide a declarative/atomic infrastructure that are doing it poorly...but, are quite popular. NixOS seems like an ideal tool for the task; as you note, one could readily build your containers with NixOS (and I think it'd be the ideal choice for that). And, in fact, that's primarily what I was thinking of.
We've been working on Docker support in our products lately, so it's on my mind, and the way that so many lessons that have been learned in the past couple decades of systems management are kinda thrown overboard in the Docker (and other containers) community. As above where there's a sort of belief that "containers" makes the problems package management solves irrelevant. Likewise, there's a lot of throwing security out the window; a tremendous level of trust is being given to container builders.
I could rant all day about stuff like this, and there's always the risk of turning into Grandpa Simpson. So, I'll stop ranting after a summary:
Containers are cool, but a lot of people are making a lot of mistakes in their use of containers. NixOS is cool, and might remedy some of the problems I see in the way people are using containers (while also solving a number of other problems of reliable deployments, not just with containers).
>[...] taking care to change ~/.zshrc to reflect the “run commands” file of your shell if necessary
Huh, I've been wondering what the rc part of config files actually meant. The only thing I could come up with previously was "resource" file, which didn't make much sense but I never looked it up so whenever I deal with rc files, I think of them as resource files. Now I know what it actually means and can begin thinking of them as such.
Sorry for the downtime. I noticed GitHub have bumped the Jekyll version on GH Pages, so now all my links are broken from the outside. I've fixed this one; now to handle all the others!
I'm a Haskell contractor who currently works with a tech stack that looks like PostgreSQL, Haskell (backend), Haskell (frontend), and Nix. Stuff gets deployed to AWS.
things i hate about nix:
1. The nix language isn't haskell. It's a very spartan functional programming language. errors can be unhelpful and it is difficult to find thorough documentation. There's not much sugar and it has few abstraction facilities beyond higher order functions (like ML modules or Haskell type classes). In order to grok nix, I recommend reading the nix manual[1] thoroughly and this series of blog posts [2]. Honestly though nix would be much more powerful if it were embedded in a full fledged functional language instead of trying to focus on just package description. i am many orders of magnitude less efficient at writing nix as i am haskell. guix looks interesting but i haven't tried it seriously: check it out too.
2. the caching system is a little boned. if a cache goes down, the builder will wait forever to get the metadata from the server instead of ignoring it. there is a timeout setting but it only applies to downloading the actual binaries, not the .narinfo files. the workaround is to disable binary caches for that invocation. it is an annoyance since i often work on projects with flaky cache servers.
things i like about nix:
1. i haven't fucked up my computer with NixOS yet. upgrading everything Just Works. If it doesn't Just Work, reverting Just Works. You have to go rather far out of your way to put a NixOS system in an inconsistent state. I might be a somewhat reckless user, but i used to put my Ubuntu installations in inconsistent states regularly.
2. i can create a good sandboxed environment for any project with relatively little effort. it doesn't matter how many languages or arcane dependencies there are. there are no subtle bugs caused by interfering components: if there's interference it's a build error; if there isn't, you're good.
3. if you've used a build system in anger and you can only come up with two complaints and neither of them are "it has trouble building the thing", then you've found a good build system. i've never had to worry about dependencies, reproducible builds, sharing binaries with colleagues or anything. in spite of all the warts of the language and the byzantine user experience, by god it works.
Can you give an example of what you have tried to do in Nix that you couldn't do well due to lack of power? I imagine it is something rather fancy since for most configuration tasks Nix is significantly more powerful than other config file languages.
Number 2 sounds like a legit bug rather than an inherent problem with the design. If you haven't already maybe you can file an issue on Github and it could get the timeouts to apply correctly.
Hm, i don't think i have a specific example of the first issue that isn't under NDA. In the abstract, "higher order" derivations, that is derivations that produce other derivations which in turn get built are a bit cumbersome to work with. Nix is perfectly capable of expressing complex dependencies which just invites a person to push it to its limits. The limits are purely practical. You can go as far with nix as you are patient with working in a barebones language.
Number 2 is probably a bug, yea. It's certainly not a design flaw. It's just a wart. Unfortunately, even though nix has a strong community of great contributors, it's a very ambitious project and so warts and rough edges are part and parcel of the nix experience.
I can't speak for NixOS specifically, but in GuixSD (a closely related project) this is handled at the service layer, an I imagine the same must be true for NixOS. The OS declaration specifies that, for example, the PostgreSQL daemon should be running with a specific configuration and the init system will run it when the system is instantiated. Your database runs as normal, and you would back up your state as normal. Functional configuration management provides an extremely clean separation of stateless from the stateful.
So at Obsidian Systems[1]*, my current shop, we deploy by building the entire system image and then transferring it to the server, and then activating the server. The NixOS master config file lets you specify global services like a PostgreSQL server and its initialization script.
That said, I've not used either in production. But, Nix was the first time I've looked at a new package manager and thought, "OK, someone finally improved on RPM/yum or deb/apt." Most of the time, I look at new package managers and just find myself running down a list of all of the ways they've failed to even replicate the power/flexibility/reliability of those now-ancient package managers, and usually without any really good reason. It's a cool side effect of a superior package manager that so much other stuff comes easily or automatically.
Anyway, this is a really cool idea, and something I want to look into more. You get so much of the "declarative and predictable" elements you want in a service-based architecture for free with Nix, while so many other solutions are bolted on clumsily.