So, I read about a similar-ish tool to this recently, `devenv` - it sounds like both tools are based around Nix.
The other article (talking about `devenv`) was discussing a migration away from running Vagrant.
I had questions then that I still have now with this tool: assuming this, like `devenv` doesn't directly run a VM, how exactly do you solve actual platform differences - e.g. it's quite common to have developers using macOS or Windows, and production servers running a Linux distro.
Sure, some things work the same or close-enough to the same, but even with scripting languages (no aot compiling) that have pretty good cross platform support, there are differences either in features, extensions, or in system level dependencies (i.e. a database server, cache server, etc).
Vagrant is one solution to this problem, as is "Docker in a VM", albeit a little less flexible IMO - essentially you run a "close to production" environment inside a VM, with zero worries about what the host environment is, because the software is still running in basically the same environment as prod. The rise of Arm workstations has made this interesting, but Debian 12 on Amd64 is still a heck of a lot closer to Debian 12 on Arm64 than it is to macOS or Windows on anything.
So what is the Nix solution to this problem?
It sounds like the best you'd hope for would be to run Nix inside a VM, potentially managed by something like Vagrant (thus giving you a reproducible VM running a reproducible environment), but a number of comments I've seen about using `devenv` or nix made a point of "no VM required".. so that just makes me wonder, am I missing some vital piece of information about Nix, or are these people just running much simpler dev environments than I'm used to?
Using Nix as a package manager works best with a repository called "Nixpkgs".
Nixpkgs focuses on reproducible builds, that means that for the same inputs, you always are going to get the same binary output.
All of Nixpkgs are built using nixpkgs, and they don't depend on any library outside nixpkgs, including glibc and compilers.
That means that you can "lock" your packages into a version, and you ensure that it will run the exact same version and configuration in all machines that you install it, no matter the underlying OS or how old/new it is, glibc problems etc...
This is the power of Nix.
All of this can be done via a simple
Flake.nix -> define the system
Flake.lock -> automatically generated, defines the exact version of nixpkgs among others.
(Can also be done via channels but flakes are better imo)
Nix runs alongside other distributions in various OSs, including OSX. (Windows is being looked at, do not hold your breath.)
The cross-platform capability of `flox` comes from our usage of Nixpkgs, which includes allowance for some of the differences between platforms and makes them less of an issue.
If some piece of software has a specific difference when run on different platforms and you rely upon that difference, then your need to use that platform in some way: native, VM, translator, etc. Nix does make it easier to manage, build, distribute, multiple kinds of software.
Flox environments leverage this same foundation to expose the same environment on multiple systems and we plan to work on this more. What in particular would you be looking for?
> The rise of Arm workstations has made this interesting, but Debian 12 on Amd64 is still a heck of a lot closer to Debian 12 on Arm64 than it is to macOS or Windows on anything.
The kind of default/minimum reproducibility for most Nix-based deployments is basically a stronger version of this. It's like 'Debian 12 on AMD64 with all the exact versions and non-arch-specific build flags of all packages exactly pinned is very similar to Debian 12 on ARM64 with all package versions and non-arch-specific build flags pinned to the exact same thing'.
> Sure, some things work the same or close-enough to the same, but even with scripting languages (no aot compiling) that have pretty good cross platform support, there are differences either in features, extensions, or in system level dependencies (i.e. a database server, cache server, etc).
This is worth digging into.
> there are differences either in features, extensions
Nix will guarantee for you that you always get the exact same features and extensions unless it's truly the case that a feature is just not available on some platforms. So it takes care of differences that come from different operating systems and distros using different ./configure flags and so on.
> or in system level dependencies (i.e. a database server, cache server, etc)
Flox and competitors like it all support local process supervision/service management as well as just adding packages to an environment, so you pin down the versions and configuration options of your DB server and cache server in the environment specification as well.
> Sure, some things work the same or close-enough to the same
For things that are genuinely different (e.g., Nix itself has different sandboxing features and support on Linux because those operating systems' respective kernels also differ in their capabilities), you are still going to want to virtualize. If your production environment is NixOS, there are some pretty nice tools available for this. Otherwise you might want to do your final testing via something like Vagrant or Tart or some custom Nix-based tooling.
But if Docker-in-a-VM is good enough reproducibility for your stack, Nix will probably be a little bit better.
The other article (talking about `devenv`) was discussing a migration away from running Vagrant.
I had questions then that I still have now with this tool: assuming this, like `devenv` doesn't directly run a VM, how exactly do you solve actual platform differences - e.g. it's quite common to have developers using macOS or Windows, and production servers running a Linux distro.
Sure, some things work the same or close-enough to the same, but even with scripting languages (no aot compiling) that have pretty good cross platform support, there are differences either in features, extensions, or in system level dependencies (i.e. a database server, cache server, etc).
Vagrant is one solution to this problem, as is "Docker in a VM", albeit a little less flexible IMO - essentially you run a "close to production" environment inside a VM, with zero worries about what the host environment is, because the software is still running in basically the same environment as prod. The rise of Arm workstations has made this interesting, but Debian 12 on Amd64 is still a heck of a lot closer to Debian 12 on Arm64 than it is to macOS or Windows on anything.
So what is the Nix solution to this problem?
It sounds like the best you'd hope for would be to run Nix inside a VM, potentially managed by something like Vagrant (thus giving you a reproducible VM running a reproducible environment), but a number of comments I've seen about using `devenv` or nix made a point of "no VM required".. so that just makes me wonder, am I missing some vital piece of information about Nix, or are these people just running much simpler dev environments than I'm used to?