Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login
Ruby-Nix: Generates reproducible Ruby/bundler app environment with Nix (github.com) similar stories update story
107 points by thunderbong | karma 96016 | avg karma 7.63 2022-12-27 22:21:27 | hide | past | favorite | 18 comments



view as:

Having a completely deterministic per-project (directory) environment, no matter what language you use, is one of the best benefits of Nix. If you have 10 different Ruby/Elixir/Rust/Bash/etc. projects, you can have it set up whereby simply cd'ing into the directory (thanks to direnv integration) will set up a pure development environment, with the exact version of (say) Ruby ready to go, even with multiple different versions of Ruby between different projects, etc.

Every single language seems to have a half-assed tool to help do this sort of thing... asdf, virtualenv, etc. If you learn a little Nix, you can basically have a real solution that usurps all of these other ones, across all languages


how is this better than just using asdf where i can just put a `.tool-versions` file in the project and have it swap ruby+node+whatever to the appropriate versions?

(honest question)

https://asdf-vm.com/


Here's a good answer to that question (scroll down for comparison to asdf): https://medium.com/@ejpcmac/about-using-nix-in-my-developmen...

In my Elixir app's case, the app was not deterministically reproducible using only asdf because it had underlying dependencies (a NIF, in this case VIPS) that required either C or Rust compilation at build time, and that in turn required another stack of dependencies with specific versions (which often broke the build), and even if that was all lined up, there are outside dependencies such as SSL libraries which can make or break builds when not using something like Nix (which gives you total control over every dependency). But the funny thing is that all I had to do was specify "vips" as an input, and since Nix already takes care of giving vips whatever IT needs to build correctly, it was basically a no-op to make this work with Nix.

Given the fact that you can output a Docker from a nix recipe/derivation https://thewagner.net/blog/2021/02/25/building-container-ima... , it also supersedes Docker IMHO


Conceptually I love this idea. I love the idea of them being able to build AWS/GCP/VM images of the same thing even more. The place it falls down for me is that for it to be truly valuable everyone on the team needs to be bought in, and Nix is in my experience not the friendliest of tools. I have nasty images of the build breaking and everyone just being baffled by it, which is certainly an issue with Docker as well, but at least Docker is just running some shell commands during build.

Getting buy-in from your team can happen gradually; initially I think you'd only need 2 people with basic competence to get past most build difficulties (in order to avoid the "hit by a bus"/"vacation" problem), and the others can learn as those 2 go (and communicate how they fixed things). Docker certainly isn't just "running some shell commands"

Here's a link to one of a few blogposts about building container images with nix: https://thewagner.net/blog/2021/02/25/building-container-ima...

Here's a few good links to get started:

https://nix.dev/

https://nixcloud.io/tour/?id=1 < This one's a pretty cool interactive nix language tour that works by asking you to solve progressively more challenging problems and then validates the solution by actually running it- I love this approach to learning a language.


Why shouldn't this be upstreamed?

I assume folks downvoted this because they figured it was asking about Ruby or Bundler as upstream projects.

But looking at it from a perspective where Nixpkgs is the upstream: what does this introduce that would be unwelcome in Nixpkgs' bundlerEnv, or perhaps situated so it can share code with the existing implementations?


I just found it presumptuous. Who ever said it shouldn’t be upstreamed?

Trialing new designs in your own space is a pretty common pattern and there’s ample history of good ideas being adopted upstream once proven.

Or sometimes you just might not have the energy for it. It’s okay for your gift to the world to merely be available, without pressure to go farther.


Since this is a flake, there’s basically no reason to upstream other than discoverability. Thats one of the benefits of the flake model vs non-flake.

I generally just install Ruby/rails directly on my Mac…

I’m starting to switch to local rocker-compose for dev, and also for deploying simple apps to single VPS instances.

Should I learn Nix? What’s a good starting place to do that?


> What’s a good starting place to do that?

In general, check out nix.dev as a starting point.

For a deep dive on how it works with a focus on modern features, check out this blog series: https://tonyfinn.com/blog/nix-from-first-principles-flake-ed...


You don't necessarily have to know the Nix language upfront, but it helps (otherwise your eyes will glaze over in parts you'd otherwise grok right away). Honestly, it's not a terrible starting point. Nix has been described as "JSON with a different syntax, plus pure functions" which does come sort of close- It's not actually as complex as it looks at first.

There's a very cool interactive tutorial here which fit the way I like to learn pretty perfectly: https://nixcloud.io/tour/?id=1 It's an actual Nix interpreter running in the browser (thanks to emscripten) that validates your answers by actually evaluating them, through a series of progressively more difficult questions.


> I generally just install Ruby/rails directly on my Mac…

Not sure how long you've been doing ruby dev but that has historically been a path to a lot of pain, especially once native gems come into play.


What do routine dependency updates look like with this? Can I `bundle outdated` and `bundle update`?

Unfortunately, nix is an extremely unfriendly thing in therms of documentation. It almost impossible to graps the meaning of its syntax, although people claim that nix is extremely useful. Nowadays the documentation (or a book) is the only concern that nix's team should be tackling.

There is a section called "Building a Docker image". Why do you need Docker if you are using Nix? It is like creating an environment inside another environment(?).

I would assume it’s mostly for deploying to systems that expect Docker images like Kubernetes, fly.io, etc

Legal | privacy