Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I've tried using Nix a few times. The idea is in principle not bad, but the actual deployment for, say... an API endpoint? Horrendous.

Problems include:

1. Scripts deployed almost never appeal to /usr/bin/env, they tend to hardwire interpreters to /bin/sh. This flat out doesn't work in NixOS, and the Nix team is ideologically opposed to maintaining a compat layer for specific cases like this.

2. Compiled binaries are compiled to this SPECIFIC version of Nix. That may not seem like a bad thing, but the reality is that it's very abusive to work with. Your binaries cannot even be invoked becuase they cannot find their links (including, you know, the C bootstrapping lib). This means you can make an executable on your dev box, try and push it to prod, and because prod doesn't have something like a dtrace library the entire system is incompatible with your executable.

3. There are tools to assist with these problems, because they're so common. However, they themselves are full of edge cases they don't solve for that they're very hit-or-miss. While this isn't bad in and of itself, it tends to make the established userbase very unsympathetic and often very formulaic when you approach them with more subtle linking issues. This can be quite frustrating.

I found the entire system somewhat unworkable. I also feel like Docker or Rocket solves a lot of the practical problems I have there, despite protestations. Container images are perfectly reproducible, but also easy to update. They also tend not to rip themselves apart if you, in a moment of intellectual weakness, give a slightly confusing order to the nixos package manager and rip your system in half.



I don't know what software you were using, but it doesn't sound like Nix.

1) Your scripts should be part of a package. I don't know about Nix, but in Guix we have a build step that patches shebangs to remove the nasty /usr/bin things and replace them with references to the right executables in the store.

2) You can copy the closure of a build, that is the build your are interested plus all of its recursive dependencies, to another machine and it will work just fine. In fact, this feature is a big part of how we produce the Guix binary tarball. Yes, the output of a build is a function of the version of Nix/Guix used to build it, but that has no bearing on whether or not you can run the resulting binaries on another machine.

3) Given that problems 1 and 2 are invalid, I don't know what else to say to this.

Docker and Rocket do nothing to solve the problems that Guix and Nix solve. Container images are not reproducible. You and I can build an image from the same Dockerfile and I guarantee that the checksums would be different. Reproducibility is being able to build the same thing N times on M different machines and get the same exact result, bit for bit. Guix and Nix are getting us to this goal, Docker and Rocket do nothing. Also, you cannot "rip your system in half" with Nix or Guix. They provide roll back facilities to undo bad changes to user profiles or the system configuration.


> I don't know what software you were using, but it doesn't sound like Nix.

I love how the initial reaction by every Nix user is to imply I'm a liar or just titanically stupid. Like it's not possible that a relatively new linux distribution that has just undergone a major overhaul of its package management system might still have bugs or issues.

No. NixOS is perfect for everyone today. Just completely rewrite every deploy script you have from the ground up. Having trouble? Don't worry! The documentation is "getting better."

> Your scripts should be part of a package. I don't know about Nix, but in Guix we have a build step that patches shebangs to remove the nasty /usr/bin things and replace them with references to the right executables in the store.

Sorry, but I will not be writing an OS-integration package for every specific software deploy during development. It's unlikely to even imply that I should be doing this during development just to get off the ground. I tried to use NixOS as an environment for development for Golang and Java and found it frustratingly at odds with all existing tooling. The only languages I found that seemed well supported was haskell and C, and I don't ship code on either of those platforms anymore.

It was doubly unlikely early this year. The documentation was in utter disrepair and more than two Nix developers told me on twitter, "It is very difficult to do unless you are a contributor." It was also the case that many pre-existing packages were done incorrectly, still suffering these problems. Golang's package was one of them.

> but that has no bearing on whether or not you can run the resulting binaries on another machine.

Copying a closure to deploy software projects currently in development is an extremely intensive step, and many packages had outstanding bugs that don't do this.

Furthermore, existing deploy tools like Puppet, Salt and Ansible all have extreme difficulties managing this model, but Nix (at least at the time I examined it) didn't offer very good tools for actually distributing said closures in a cloud services environment.

> Container images are not reproducible. You and I can build an image from the same Dockerfile and I guarantee that the checksums would be different.

It's not the responsibility of the dockerfile to maintain this immutability. It's the responsibility of the environment the dockerfile is executed in.

Which is probably why Golang was specifically such a problem, it has a really miserable story for actually making reproducible builds with locked deps.

Given a specific git SHA for a project with locked dependencies, it is absolutely reproducible and will produce the same image SHAs every time.

P.S., at the time NixOS was going through a major update and it was possible to install a version of Nix onto NixOS that was not entirely compatible. This ruined the install while still using Nix commands. If that bug has been fixed, great, but it was a known issue and I was not the only person in IRC asking for help with it. You lost your ability to roll back.


the moment your Dockerfile has apt-get update and apt-get install is the moment your docker images stop being reproducible unless you take extreme measures like mirroring all deb repos you have in your sources.list.

disclaimer: happy docker user here.


Where is everyone getting the idea that Docker is for creating reproducible environments? I know when I first heard about Docker, it was mentioned, but Docker does not claim to provide that. Seems like a confusion between distributable and reproducible.


The execution environment for a product is certainly reproducible with Docker, assuming you actually make your base image Dockerfile work in a reproducible environment as well.

You can also use Dockerfiles as units of deployment for individual software projects, which offers that.

While it is true that NixOS offers a different vision for how to solve these problems, it does so in a way I find very destructive for actual use. It seems inferior for deploying software compared to containerization (which offers immutable and composable build artifacts), and very cumbersome to work with during software development (since the value of writing nix packages during development is cumbersome and for many language environments you have to deploy the source code in the package and compile it within the closure you expect to deploy on to make any headway).

Ya'll can pretend https://github.com/NixOS/patchelf doesn't exist because these problems are incredibly irritating, I guess.


The "Cattle vs. Pets" argument is basically that. You want all the cattle to look the same and you can't do that if they are modifying themselves.


Yeah, the point of docker is you build one image, test that, and share it around and that image should always work. The build is a different story.


> the moment your Dockerfile has apt-get update and apt-get install is the moment your docker images stop being reproducible unless you take extreme measures like mirroring all deb repos you have in your sources.list.

So don't do that. I can put mutable software into Nix packages because I can force arbitrary shell commands with non-deterministic output. That power exists. It'll just break the guarantees we'd like to enforce.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: