It’s also developer-friendly because of its excellent wiki.
I learned Linux doing everything by hand on a Slackware system, then moved to Ubuntu after ~8 years when I realized I’d stopped learning new things. Then a couple years ago I realized I didn’t understand how a bunch of things worked anymore (systemd, pulseaudio, Xorg, more). I looked at various distros and went with Arch because its wiki had helped me almost every time I’d had an issue.
Speaking of distros, I’m currently learning Nix and NixOS. It’s very nice so far. If I can learn to build packages I’ll probably replace lobsters-ansible with it (the recent issues/PRs/commits tell a tale of my escalating frustration at design limitations). Maybe also my personal laptop: I can experiment first with using nix to try xmonad first because it’s mostly configured by editing + recompiling) and deal with python packaging, which has never worked for me, then move completely to NixOS if that goes well.
I switched from Mac to NixOS and couldn’t be happier. At work we use Nix for building Haskell projects as well.
The Arch wiki actually seems to be the only good documentation for using the advanced functionality of newer freedesktop components like pulseaudio, or much older software like Xorg.
But I’ve noticed it’s documentation for enterprise software like ZFS is usually hot garbage. Not surprising given the community. The recommendations are frequently hokey nonsense: imaginary micro-optimizations or blatantly incorrect feature descriptions.
What do you find better about nix for making packages than, say, making an rpm or deb? I’ve found those package systems valuable for large scale application deployment. Capistrano has also been nice for smaller scale, with its ability to deploy directly from a repo and roll back deployments with a simple symlink swap. And integration libraries are usually small enough that I’m comfortable just importing the source into my project and customizing them, which relieves so many minor tooling frustrations overall.
Of course in the end the best deployment system is the one you’ll actually use, so if you’re excited about packaging and deploying with nix, and will thus devote more time and energy to getting it just right, then that’s de facto the best option.
What do you find better about nix for making packages than, say, making an rpm or deb?
I don’t, yet. The “If I can learn to build packages” sentence links to an issue I’ve filed. I was unable to learn how to do so from the official documentation. I’ve almost exclusively been working in languages (PHP, Python, Ruby, JavaScript) that rpm/deb have not had good support for, prompting those languages to each implement their own package management systems that interface poorly or not at all with system packaging.
I’ve used Capistrano, Chef, Puppet, and currently use Ansible for deployment. Capistrano and Ansible at least try to be small and don’t have a pretensions to being something other than an imperative scripting tool, but I’ve seen all of them break servers on deployment, let servers drift out of sync with the config, or fail to be able to produce new deployments that match the existing one. Nix/NixOS/NixOps approach the problem from a different direction; it looks like they started from what the idea of system configuration is instead of scripting the manual steps of maintaining one. Unfortunately nix replicates the misfeature of templating config files and providing its own config file on top of them instead of checking complete config files into a repo. Hopefully this won’t be too bad in practice, though it’s not a good sign that they implemented a programming language.
I appreciate your closing sentiment, but I’m not really trying to reach new heights of system configuration. I’m trying to avoid losing time to misconfiguration caused by services that fundamentally misunderstand the problem, leading to booby traps in common usage. I see almost all of my experience with packaging + deployment tools as a loss to be minimized in the hopes that they waste less time than hand-managing the global variables of public mutable state that is a running server.
Hmmm. I don’t think the problems you listed are 100% avoidable with any tool, just easier in some rather than others.
I like Puppet and Capistrano well enough. But I also think packaging a Rails application as a pre-built system package is definitely the way to go, with all gems installed and assets compiled at build time. That at least makes the app deployment reproducible, though it does nothing for things like database migrations.
What do you find better about nix for making packages than, say, making an rpm or deb?
Let me show you a minimal nix package:
pkgs.writeScriptBin "greeter" "echo Hello $1!"
Et voila! You have a fine nix package of a utility called greeter that you can let other nix packages depend on, install to your environment as a user or make available in nix-shell. Here’s a function that returns a package:
greeting: pkgs.writeScriptBin "greeter" "echo ${greeting} $1!"
What you have here is a lambda expression, that accepts something that you can splice into a string and returns a package! Nix packages in nixpkgs are typically functions, and they offer an a great amount of customizability without much effort (for both the author and the user).
At work, we build, package and deploy with nix (on the cloud and on premises), and we probably have ~1000 nix packages of our own. Nobody is counting though, since writing packages doesn’t feel like a thing you do with nix. Do you count the number of curly braces in your code, for instance? If you’re used to purely functional programming, nix is very natural and expressive. So much so that you could actually write your application in the language if it’s IO system were designed for it.
It also helps a lot that nix can seamlessly be installed on any Linux distro (and macOS) without getting in the way of its host.
If only ZFS from Oracle hadn’t had the licensing compatibility issues it currently has, it would probably have landed in the kernel by now. Subsequently, the usage would have been higher and so would the quality of the community documentation.
If I can learn to build packages I’ll probably replace lobsters-ansible with it
Exactly. I don’t have much experience with Nix (none, actually). But in theory it seems like it can be a really nice OS-level replacement for tools like Ansible, SaltStack, etc.
This is exactly what NixOps does! See here.
Thanks for the video. I’ll watch it over the weekend!
Curious - are you also running NixOS on your personal machine(s)? I’ve been running Arch for a long time now but considering switching to Nix just because it makes so much more sense. But the Arch documentation and the amount of packages available (if you count the AUR in) is something that’s difficult to leave.
Yes, I’m using it on my personal machine :). I wouldn’t recommend switching to NixOS all at once, what worked for me was to install the Nix package manager, use it for package management and creating development environments, and then only switch once I was fully convinced that NixOS could do everything I wanted from my Ubuntu install. This took me about a year, even with me using it for everything at work. Another approach would be to get a separate laptop and put NixOS on that to see how you like it.
Even as a Ubuntu user, I’ve frequently found the detailed documentation on the Arch wiki really helpful.
I really want to use Nix but I tried installing it last month and it doesn’t seem to have great support for Wayland yet which is a deal breaker for me as I use multiple HiDPI screens and Wayland makes that experience much better. Anyone managed to get Nix working with Wayland?
Arch’s wiki explaining how to do everything piecemeal really seems strange given its philosophy is assuming their users should be able to meaningfully help fix whatever problems cause their system to self-destruct on upgrade. It’s obviously appreciated, but still…confusing, given how many Arch users I’ve met who know nothing about their system except what the wiki’s told them.
I gave up on my nix experiment, too much of it is un- or under-documented. And I’m sorry I derailed this Arch discussion.
I’m happy to help if I can! I’m on the DevOps team at work, where use it extensively, and I did a presentation demonstrating usage at linux.conf.au this year. All my Linux laptops run NixOS and I’m very happy with it as an operating system. My configuration lives here.
Ah, howdy again. I’m working my way through the “pills” documentation to figure out what’s missing from the nix manual. If you have a small, complete example of how to build a single package that’d probably be pretty useful to link from the github issue.
I made a small change to the example to get it to build, and I’ve added it as a comment to your issue.
Domain Driven Design by Eric Evans is a classic modeling book, but a hard read. I’ve heard that Domain-Driven Design Quickly by Abel Avram & Floyd Marinescu is a better, shorter version but haven’t read it.
I got a lot out of Joe Celko’s Data & Databases on database design and, his puzzle books SQL for Smarties and SQL Puzzles and Answers puzzles were so fun and weird they helped me really internalize relational dbs.
I just started Scott Wlaschin’s book Domain Modeling Made Functional and Debasish Ghosh’s book Functional and Reactive Domain Modeling. I’m only about a chapter into each, so I can’t give a significant opinion yet, but they’re both interesting takes on modeling.
Jon Bentley’s Programming Pearls books and Writing Efficient Software have lots of the bitpacking kind of stuff you’re getting at in your mention of Stockfish.
Sandi Metz & Katrina Owen’s book 99 Bottles of OOP breaks down a toy problem in a bunch of different directions and points out where approaches succeed and fail at responding to change or preventing bugs.
I’m halfway through Scott’s book you mention. It’s really good! It gives me confidence to adopt the naming convention that I instinctively felt was right, when I saw no other comments about naming in pure FP literature or blogs. It’s my first intro to DDD, and it finally makes sense to me now. Not every app will require DDD, but it makes sense for business apps. The downside to adopting the business’s ubiquitous language is that you don’t have much opportunity to do cool stuff with FP concepts, but that’s fine, there is opportunity to use cool ideas in architecture stuff, like an algebra of domain object modifications.
I just bought and read Domain Modeling Made Functional on the basis of this comment and have found it really illuminating. Despite the name I would say that a lot of the concepts in it will be very applicable even in non functional settings provided the overall architecture is more functional (i.e event based in some sense).