Install prebuilt packages without root, from nixpkgs

Refactoring “instantiate” and “build” pipeline

The support staff has helped me figure out why the previous project where I compiled packages is suspended. When we download the package index, that index contains the names of programs which can mine cryptocurrency. The presence of those names on disk in combination with other circumstances created by permitted uses causes an abuse detection heuristic to suspend the project.

I assume Glitch won’t publish the exact abuse detection heuristics. But even without exact knowledge of the rules, we can make it a lot more obvious that we’re not doing crypto mining.

The design of Nix turns out to be pretty handy in this case. In building a package from the package index, there are two steps in the process. First is a relatively quick step called “instantiation,” which takes a high level specification of the package, figures out the dependency graph, and produces a set of files called “derivations” containing detailed instructions on how to build the package and its dependencies. Second, the actual building will run those steps, which involves downloading source archives and running compilers, and which takes a long time for the larger packages. Nix has built in functionality for transmitting derivations over the network.

I’ve split up the build system into two projects—one for instantiation and one for building:

tmpnix-diagram

This leads to two nice properties:

  1. The project that instantiates will download the package index and thus contain references to software that can mine cryptocurrency, but it uses very little resources and doesn’t stay online for long.
  2. The project that builds will use its entire share of CPU for as long as it takes to build, but because we only copy over the relevant derivations, we can avoid having any references to cryptocurrency-specific software in the project.

Although if you wanted to build software that can mine cryptocurrency, I think this approach wouldn’t work. But there are cool things to do other than that.

Switching to Nixpkgs stable

The normal Nix installer by default sets up the Nixpkgs package index at a so-called “unstable” channel, which contains the latest software, updated for any kind of changes. Another “stable” channel gets “conservative updates for fixing bugs and security vulnerabilities” (Nix channels - NixOS Wiki).

I’ve liked rolling releases in other distributions, but the way Nix builds packages results in a lot of extra work for rolling releases. Nix packages are like nodes in a Merkle DAG of runtime- and build-dependencies. So if a there’s a minor version bump to a library referenced by another library used in a compiler used to build a dependency of your package, you’re gonna end up with a new copy of your package. And there’s no “just dynamically link to the new library” in Nix. As things are now, you’ll have to compile everything.

It must be a lot of work when there’s a change to glibc, which I believe must find itself within almost all package transitive-build-dependencies (I think the Nix term for that would be ‘derivation closure’ or something). Within the 6-month lifetime of the previous stable release, glibc had 5 releases. During that time, it had 22 releases in the unstable channel.

My appetite for recompiling everything day to day is toward the low end, so I’ll be using the stable channel going forward. Having new packages is one of the goals of this work, but I think we’re still getting that, relatively speaking. The current stable release is a release called 21.05, while the project containers are on a release called 16.04, both presumably using year.month style versioning.

Demo

random ASCII art bonsai tree powered by cbonsai
View source

What a neat program this is:

It’s actually packaged in Ubuntu (Ubuntu – Details of package cbonsai in impish), but we can’t install that in our project containers because we have a much older Ubuntu release, and we don’t have root access, which apt needs to do its package management.

Also, remember that thing about Ruby having problems with Glitch’s reverse proxy, where it turned out to be caused by an outdated version? That’s another place where it sure would be nice to have an updated package.

So I’ve put together an example app where I install cbonsai and Ruby from Nix. If you wanted a webpage that shows you a random ASCII art bonsai tree, it’s taken years to get to this point, but you can now have that on Glitch.

3 Likes