Discover more from hrbrmstr's Daily Drop
Drop #311 (2023-08-07): Dirt Simple Package And Project Re-re-reproducibility
Nix; Devbox; Suggested Reading
There are some big things in the first two sections, so we take a lighter approach for the third to avoid overwhelming folks.
For Bonus Drop subscribers: you will most assuredly get an extra issue. The weekend was consumed by the wonder that is Down East Maine, and there was just no time left to give proper pen-time to the extra edition.
Nix was created by Eelco Dolstra as part of his Ph.D. research at Utrecht University in the early 2000s. The project aimed to address issues with traditional package management systems, such as dependency Hades and lack of reproducibility. Nix takes a unique approach to package management by treating packages as values in purely functional programming languages, ensuring that they never change after being built.
Over the years, Nix has grown into a powerful package manager with a large and active community. The Nix Packages collection (Nixpkgs) is maintained by the community and officially backed by the NixOS Foundation. With over 80,000 packages, Nixpkgs is one of the largest repositories of its kind, offering a wide range of software for users to choose from. The NixOS organization on GitHub hosts the sources of all official Nix-related projects, including the Nix package manager itself.
Nix is extremely useful for developers, data scientists, and anyone who needs to care about reproducibility. It makes it incredibly straightforward to automatically set up the build environment for pretty much any package. Given a Nix expression that describes the dependencies of your package, the
nix-shell will build or download those dependencies if they're not already in your Nix store. It will then start a shell in which all necessary environment variables (such as compiler search paths) are set. Note that Nix can be used not only for package management, but also to manage system configuration.
Asking folks to switch package managers is not a small request. So, here are some of the main pros of Nix (apart from those you'll see in the middle section):
Nix builds packages in isolation from each other, ensuring that they are reproducible and don't have undeclared dependencies. This means that if a package works on one machine, it will also work on another.
Nix makes it easy to share development and build environments for projects, regardless of the programming languages and tools used. This allows for seamless collaboration and reduces the “it works on my machine” problem. (This shines even more in the next section)
Nix ensures that installing or upgrading one package cannot break other packages. It allows you to roll back to previous versions and ensures that no package is in an inconsistent state during an upgrade.
Nix is a cross-platform package manager, working on Linux, macOS, WSL2, Docker, and more. This makes it a superb choice for developers working in diverse environments.
As noted above, it has scads of packages, ensuring that you can find almost any package you need. And, the community process means you'll be able to get help adding in ones that aren't there.
Nix allows you to compose software at build time with maximum flexibility, and with builds being as reproducible as possible.
I'm in the process of migrating from Homebrew to Nix (mostly due to how impressed I am with devbox), and will provide updates on that over the coming weeks/months.
You can, and should!, also check out b0rk's notes on Nix to see how Nix machinations work.
On my personal macOS system, I'm working on an unexpected side project that will eventually run in a Linux environment. Some of the components involved are: Node.js, Apache Solar, Apache NLP, R, and a few others. This endeavor did not start out as a side project. It was merely a crazy idea that I was doing just for fun/learning. So, given the tinkering nature of it, I had no “Docker”, “Dev Container”, “VM”, or even reproducibility plan, and — as a result — became just a tad frustrated with the just-subtle-enough differences between environments.
Having to retrofit reproducibility into this now bigger-than-a-breadbox project, I asked Perplexity how I should go about doing so. It gave me a handful of suggestions, which is where I learned about the existence of the dark magic that is Devbox.
Devbox is so extensive, I cannot do it justice in a tiny section. So, I will introduce it here and ask (nay, beg!) y'all to glance at their extensive documentation (but actually read their initial setup bits) and just install it:
$ # i stil dislike encouraging this curl/bash dance $ curl -fsSL https://get.jetpack.io/devbox | bash
and follow their guide (R folks can either hold their nose or substitute “R” for the Python examples).
Ultimately, Devbox is “just” a command-line tool that enables us to easily (deliberate use of that word) create isolated shells for development. By defining the list of packages — including things like R/Python packages — required by our development/project environments, Devbox uses that definition to create an isolated environment tailored specifically said application/project. This eliminates the need to manually install and configure each package, saving time and reducing the risk of conflicts between different packages or versions. It's kind of like Nix and Docker had a kid, especially since Devbox relies heavily on Nix.
This isolation ensures that any development/project environment is consistent and reproducible, making it easier to collaborate with other folks and deploy apps across different platforms (which is my present use case).
Devbox is not just about “packages”, too.
setup scripts to be run
use or create plugins for various components such as Postgres, Caddy, and Nginx, which makes it easier to get started with them, since they all require additional setup after basic installation
managing dependencies between Nix expressions; while each Nix expression may be isolated, you may need a specific combo for your project to work properly. For this, Devbox relies on Nix's “Flakes” ability. (You'll need to read that since I could write a whole post on Flakes.)
easily manage services that need to run in your project
automagically create Docker-compatible containers for deployment
automagically create VS Code Dev Containers for development
use Devbox in CI/CD actions, which can truly help avoid wasting an entire day fiddling with Actions configs.
You also get your regular tools and local environment variables (and more) for free.
There's a bonkers cool VS Code extension for it that does some super cool automagic things for you when working inside a Devbox-managed environment.
And, you can kick the tyres in your browser vs. experimenting on your own system.
I'm glad Devbox has only been around since February of this because it would have been a shame to have had this available for longer and not have used it until now.
You've got alot to take in with Nix and Devbox (if you aren't using both already). So, we'll take this opportunity to provide some other blog/newsletter to add into your RSS feeds/inbox, or just read about a new cool thing:
There's a new slices package in the Go standard library that I'll likely never write a section about, but should be on your radar if you use Go in any way. It includes many useful functions for sorting, managing, and searching slices.
This is a neat tool that combines AI and some other tools to help you create vector icons from a basic prompt.
If you're at Hacker Summer Camp in Vegas this week, please be kind to yourself and keep hydrated, touch no outdoor concrete/metal with bare skin, and don't ask your liver to do unnatural things. ☮