background grid image
Image for post determinate-nix-installer
Feb 27, 2023 by Graham Christensen

Introducing the Determinate Nix Installer

We at Determinate Systems are extremely excited to announce the release of the Determinate Nix Installer, a brand-new installer for Nix. You can run the installer on a variety of systems, including macOS, Linux, Windows via WSL2, and more, with this command:

Terminal window
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install

Check out the Zero to Nix quick start for a more in-depth look. In this post, we’ll cover how our new installer improves on the current official installer, why and how we built it, and how we envision its future.

Why installing Nix is a complex problem

Sometimes, installing software is straightforward. You fetch a binary from a URL, you copy it to a directory on your PATH, and you’re good to go. But sometimes things aren’t nearly so simple. Nix, as powerful and transformative as it is, falls firmly in the “not nearly so simple” camp. Far from just a static binary that you can fetch, copy, and call it a day, Nix requires a broad set of changes to your system, from creating new users to installing and running a daemon to creating a root volume and beyond. Nix installation is a non-trivial problem—and one that by definition can’t be solved by Nix itself.

Currently, the official installer for Nix is a Bash script that does the job. It’s been used with success many thousands of times in various settings. Some of our team members have even worked on the official installation script. It’s widely used because it works. But for reasons that we’ll lay out here, we’ve felt for some time that the official installer has shortcomings that make Nix onboarding more challenging than it needs to be.

A fresh start

From our perspective, the current official installer has three main problems:

  • It’s written in Bash. We love Bash here at Determinate Systems, but we think it’s unsuitable for something as fine-grained as installing Nix. Different Bash implementations have subtle differences that make it hard to eliminate inconsistencies and edge cases—and it’s hard to discover those in the first place because Bash is all but untestable.
  • It can leave your system in an awkward “in-between” state, with some installation actions successful and others not. The installer may, for example, successfully create a root volume but then fail to create the appropriate system users. But awkward or broken state is something that Nix is supposed to free you from.
  • Relatedly, it offers no built-in way to uninstall Nix, leaving people to seek out help on Github and Stack Overflow. But we suspect it would help to spur Nix adoption if users could install Nix with complete confidence that they could undo all system changes required by the installation process with a single command: /nix/nix-installer uninstall (the installer removes itself when you uninstall).

We didn’t think that “improve the existing Bash script” was a sufficiently radical approach, so we began discussing a vision for a new installer internally. Later, we saw the installer discussion on the NixOS Discourse and enthusiastically joined the installer working group. In that group, we’ve kept group members apprised of our progress and discussed what the Determinate Nix Installer would need to provide to be broadly adoptable by the Nix community. We think it’s well on the way to being that, but we hope that this release prompts many rounds of community feedback.

Core differentiators

We believe that the Determinate Nix Installer offers two main advances:

  • We wrote it in Rust instead of Bash. The chief advantage of Rust here is that it deftly sidesteps any conceivable problems with differing Bash implementations, and because Rust supports a wide range of build targets, the Determinate Nix Installer can support a wide range of systems, including systems without Bash installed. Beyond that, Rust offers robust error handling, a fantastic type system, and great libraries like clap for building CLIs and Tokio for asynchronous programming. The installer was and will remain a joy to develop, something that can rarely be said of Bash scripts.
  • We introduced the concept of an installation receipt. This is a JSON file that indicates what has already been accomplished by the installer—and what hasn’t. It’s stored under /nix and keeps all the information the installer needs to uninstall Nix seamlessly. That means deleting all of the volumes, directories, files, users, and groups that the installer created as well as surgically undoing changes to files you need to keep around (like bashrc).

A flexible installer

Above all, we want our installer to work seamlessly in any environment where Nix can work its magic:

  • On your desktop, laptop, or server, whether manually or using automated approaches like mobile device management (MDM).
  • In continuous integration and continuous deployment environments. We provide a GitHub Action for the Determinate Nix Installer, but it should be adaptable to any CI system.
  • In virtual machines and OCI containers.

To that end, we’ve provided an opinionated default experience configurable enough to meet more specific requirements. The opinionated part is that the Determinate Nix Installer installs Nix with Nix flakes and the unified CLI enabled. Although flakes and the unified CLI remain experimental features of Nix, we’re confident that new users should adopt them now and that more seasoned Nix users should make the transition ASAP.

In terms of configurability, the Determinate Nix Installer provides a range of CLI flags that you can use to customize the experience. To give some examples, running nix-installer install —no-confirm disables the default manual confirmation step (good for things like setup scripts), nix-installer install --init none installs Nix without needing an init system like systemd (good for things like Docker containers), and nix-installer install --extra-config enables you to supply extra Nix configuration to be written directly to your nix.conf file. Over time, we’ll likely add more configuration options in response to community feedback. Feel free to file an issue if you run into problems.

The future of the installer

As a company, we’re open to a wide variety of possible trajectories for the Determinate Nix Installer. We’ve licensed it under the highly permissive GNU Lesser General Public License v2.1—under which Nix itself is licensed—which should provide little obstruction to eventually making it the official installer if that’s what the community desires. We’ve also released it as a Rust library that anyone can make use of, including a potential reimagined official installer that borrows logic from the Determinate Nix Installer but provides a different set of defaults.

The initial feedback for the Determinate Nix Installer has been uniformly positive, and we’re thrilled to finally release it to the community after months of hard work. We know that it needs to prove itself in a wide variety of situations and that it will need several rounds of feedback and bug fixes. We’re eager to undergo that process in conjunction with the Nix community.

We take the core tenets of Nix very seriously. True to our name, we want to make software systems as determinate as they can conceivably be. Making Nix installation robust, seamless, and trivially reversible is a major step in that direction.


Share
Avatar for Graham Christensen

Graham is a Nix and Rust developer, with a passion and focus on reliability in the lower levels of the stack. He founded Determinate Systems, Inc to support Nix adoption at your workplace.