The solution is to decompose the docker images and make sure that every layer is hash equivalent. So if people update their Cuda version, it result in a change within the Python layers.
But it looks like Flox now simplifies this via Nix. Every Nix package already has a hash and you can combine packages however you would like.
With the Kubernetes shim, you can run the hash-pinned environments without building or pulling an image at all. It starts the pod with a stub, then activates the exact runtime from a node-local store.
Sure, it's easy to stand up a mail server in NixOS, or to just use docker/kubernetes to deploy stuff. But after a few years it felt like I don't have a single understanding of the stack. When shit hits the fan, it makes it very difficult to troubleshoot.
I am now back on running my servers on FreeBSD/OpenBSD and jails or VMM respectively. And also dumbing the stack down to just "run it in a jail, but set it up manually".
The only outlier is Immich. For some reason they only officially support the docker images but not a single clear instruction on how to set it up manually. Sure, I could look at the Dockerfiles, but many of the scripts also expect docker to be present.
And now that FreeBSD also has reproducible builds, it took one more stone away from Nix.
Also, think it's a huge ecosystem win for FreeBSD pushing on reproducibility too. I think we are trending in a direction where this just becomes a critical principle for certain stacks. (also needed when you dive into AI stacks/infra...)
We did just launch this last week after a good bit of work from the team. Steve wrote up a deeper technical dive here if anyone is interested - https://flox.dev/blog/kubernetes-uncontained-explained-unloc...
Also. Check out Farid's other posts.
There's a lot of reasons to use Nix instead of or WITH Homebrew depending on your exact needs.
Where it’s paid off for me (and where I think it actually wins) is when the problem is recreating environments: multiple machines, teammates, CI, nasty native deps, CUDA stacks, etc. At that point you’re choosing where entropy lives: in invisible drift (brew/manual installs) or in a repo you can diff/rollback.
Also, you don’t always need to go full “immutable everything.” Really depends on your needs here. Hybrid tends to be another sane path. In certain situations this can get you 80% of the upside without having to rip it all out. So kinda the "good enough" which I've seen a lot of folks do.
We (Flox) actually worked on this with Kelsey Hightower a while back - https://bsky.app/profile/kelseyhightower.com/post/3ld2rsccls...