Hacker News new | ask | show | jobs
by chrisfarms 4319 days ago
Nix, NixOS, Nix ... a thousand times Nix.

I can't believe the article doesn't mention it.

I've been using NixOS as my OS for development, desktop and we're in the middle of transitioning to using it for production deployments too.

Nix (the package manager not the distribution) solves so many of the discussed problems. And NixOS (the linux distribution) ties it all together so cleanly.

I keep my own fork of the Nixpkgs repository (which includes everything required to build the entire OS and every package), this is like having your own personal linux distribution with the but with the simplest possible way of merging changes or contributing from upstream.

I use it like I'd use virtualenv. I use it like I'd use chef. I use it like I'd use apt. I use it like I'd use Docker.

http://www.nixos.org

4 comments

Yes! The Haskell community has been using Nix to great effect and I would like to see other programmers catch on as well. Here is a great talk about using Nix targeted at Python programmers: http://pyvideo.org/video/3036/rethinking-packaging-developme...

In addition to Nix, there is also a newer project: GNU Guix. Guix is built on top of Nix but replaces the custom package configuration language with Scheme, among other differences. https://gnu.org/software/guix/

When package management is solved at the system level, our deployment situation becomes a whole lot better. I used to do a lot of Ruby programming. Wrestling with RVM and bundler was a real pain, especially since bundler was incapable of helping me with the non-Ruby software that I needed as well like libmysqlclient, imagemagick, etc. Using Nix/Guix, you can throw out hacky RVM (that overrides bash built-ins like cd!) and simply use a profile that has the right Ruby version.

Bye pip, bundler, composer, CPAN, puppet, ansible, vagrant, ..., and hello Nix/Guix!

> In addition to Nix, there is also a newer project: GNU Guix. Guix is built on top of Nix but replaces the custom package configuration language with Scheme, among other differences. https://gnu.org/software/guix/

Personally, I'm rather more keen on Nix; the language is pretty much designed for writing JSON-style configuration except as a formal programming language, which is what the vast majority of Nix code is (both package definitions and system configurations).

Additionally, with Nix, you can be close to certain that if you build something twice, you'll get the same result, because it can't access impure resources.

Finally, because Guix is a GNU project, the official repositories are going to go nowhere near non-free software. Nixpkgs contains non-free software, although disabled from installation by default. You might be a little less likely to have people help you get non-free software working on the GNU Guix mailing lists, if you happen to use any.

>the language is pretty much designed for writing JSON-style configuration except as a formal programming language, which is what the vast majority of Nix code is (both package definitions and system configurations).

Guix uses an embedded domain specific language that is also designed for easily writing package recipes, but it uses s-expressions instead of something that is "JSON-style". Also, Nix build scripts are written in Bash, whereas Guix build scripts are written in Scheme. I think that makes Guix more consistent in its programming style.

>Additionally, with Nix, you can be close to certain that if you build something twice, you'll get the same result, because it can't access impure resources.

Guix has this same certainty because it uses the Nix daemon, and the defaults are a bit stricter than Nix.

>Finally, because Guix is a GNU project, the official repositories are going to go nowhere near non-free software.

That doesn't mean that you can't host your own non-free packages or use someone else's non-free packages. But yes, Guix does not ship with packages that ask the user to give up their freedom. To me, that's an advantage.

> Also, Nix build scripts are written in Bash, whereas Guix build scripts are written in Scheme. I think that makes Guix more consistent in its programming style.

On the other hand, in order to write a Guix build script, you have to know Scheme (and whatever libraries Guix provides for this task) rather than utilising your existing knowledge of writing shell scripts.

> Guix has this same certainty because it uses the Nix daemon, and the defaults are a bit stricter than Nix.

Really? So you don't actually get access to any of the I/O Scheme libraries from Guix? My understanding (and it seems the understanding of several other people) is that while Guix uses the Nix daemon and thus derivations (and thus build processes) are pure once generated, the process for generating them from the Scheme code is not guaranteed to be so, given that the Scheme code can do practically anything.

Of course, you might not actually write non-deterministic Scheme code, but it's nice to have the guarantee that given a .nix file and a specific version of nixpkgs, the build will always come out to the same result no matter what the creator of that file has done.

> On the other hand, in order to write a Guix build script, you have to know Scheme (and whatever libraries Guix provides for this task) rather than utilising your existing knowledge of writing shell scripts.

To learn Nix you need to learn both how to write shell scripts and how to write Nix expressions. How is that better than just learning Scheme, which is very trivial to learn the basics - and for most packages, you don't really need to learn much because you can reference other packages - it's really just like a configuration file.

One of the goals of GNU is to really make Guile ubiquitous - used for configuration of packages, build processes, service configuration (via DMD) and software configuration/extension. There should be no need to learn dozens of different configuration formats and languages, scheme is the only language you'll need to be able to fully drive your OS. (Well, perhaps not strictly true, you'll probably still need to use the shell, but you'd preferably write guile scripts rather than plain bash).

> My understanding (and it seems the understanding of several other people) is that while Guix uses the Nix daemon and thus derivations (and thus build processes) are pure once generated, the process for generating them from the Scheme code is not guaranteed to be so, given that the Scheme code can do practically anything.

You can do anything from the shell too (which nixpkg can invoke) - you can even invoke guile from a shell script. The guarantee given by both systems is that the build happens in an isolated environment (via chroot), and it doesn't matter what general purpose computation happens inside the environment.

Neither Nix nor Guix make guarantees about the resulting binary from a build process - we do not yet have reproducible builds[https://wiki.debian.org/ReproducibleBuilds]. The only guarantees made by both PMs is that packages have an identity which is a hash of their source, dependencies and build instructions. Changing the build instructions results in a new derivation, so unless you have some crazy package that deliberately tries to make itself non-reproducible, you should get approximately/functionally identical binaries from building, even if they are not bit-exact. Obviously we'd like ReproducibleBuilds in both systems, to be able to authenticate the actual build via its hash.

> To learn Nix you need to learn both how to write shell scripts and how to write Nix expressions. How is that better than just learning Scheme, which is very trivial to learn the basics - and for most packages, you don't really need to learn much because you can reference other packages - it's really just like a configuration file.

Except that as a Linux admin, you probably already know how to write shell scripts anyway, and you'd be rather hard-pressed to manage a Linux system while never once having to write or read one. There's also a lot more information on writing shell scripts than Guile scripts for various common purposes.

> scheme is the only language you'll need to be able to fully drive your OS.

With a different DSL for each use, meaning you have to learn the restrictions of each DSL anyway.

> You can do anything from the shell too (which nixpkg can invoke) - you can even invoke guile from a shell script.

That's true, although in Nix's case, the derivations map directly to the source, as Nix code itself can't call out to anything (only return derivations which might) - and in theory, the build could then happen in a sandbox, making it even more likely that the result would be the same.

We might not have reproducible builds yet, but Nix is closer to having them than Guix if somebody wanted to make a research project out of it.

You could of course use a platform that doesn't depend on OS dependent binaries (like the JVM) and a package manager that likes ad-hoc and easily created repositories and that has lots of plugins available (Maven, or derivates like Gradle, SBT or Leiningen).

I worked with a lot of platforms, such as PHP, Perl, Ruby, Python, Node.js and .NET. I felt the pain of pip, easy_install, setup-tools, virtualenv, bundler, gems, cpan, pear, rvm, rbenv, npm, bower, apt-get or whatever else I used at some point or another. And I swear, in spite of all the criticism that Java or Maven get and in spite of all warts, in terms of packaging and deployment for me it's been by far the sanest. I mean, it's not without warts, heaven forbid to end up with classpath issues due to transitive dependencies, but at the very least it is tolerable.

>You could of course use a platform that doesn't depend on OS dependent binaries (like the JVM) and a package manager that likes ad-hoc and easily created repositories and that has lots of plugins available (Maven, or derivates like Gradle, SBT or Leiningen).

I don't think being locked into the JVM is a very good solution. Java libraries can depend on other non-Java components.

There are Java jars with native binaries, just sayin. Though I do like Maven and Java quite a bit.

https://bitbucket.org/xerial/sqlite-jdbc

https://github.com/twall/jna

I would be very interested in reading a detailed post about your experiences with Nix/NixOS.

I've been hearing a lot about this project, but I always thought it was just an academic experiment. I'm in the process of packaging and maintaining a Python+Javascript+Redis+PostgreSQL application and Nix certainly is something I should learn more about.

But is it hard getting packages into the Nix ecosystem? If there's too much friction or if it's too hard to resolve all the dependencies yourself before pushing your pkg, I fear it may suffer from lagging behind the latest available versions of most packages.
Everyone has to resolve their immediate dependencies anyway to push it to pip or whatever else, or nobody can install it. The only additional dependency to push it to Nix would be the language interpreter.

Nix doesn't require you to specify the entire dependency tree; each dependency specifies its own dependencies, and those are resolved during the build process.

(For the record, at least Haskell, Python, and node.js packages are pulled into the nixpkgs tree from their respective package repositories regularly, albeit many missing native dependencies; there's a separate file that you can edit and send a pull request for packages which have native dependencies.)

Yes, thank you! But people still want to "solve" the problem the hard way, I guess.

Also, "Java" is mentioned twice in the article but I can't find mention of Ocaml Functors. I thought they solved most package problems even before Nix was around?

There's a bit of missing context: the author is writing this most likely as part of his research on implementing Backpack—a systems which would being OCaml Functor-like things to Haskell.
Functors are part of the Ocaml module system, but they don't really have any relation to package management with version numbers and dependencies.