Hacker News new | ask | show | jobs
by fwip 2224 days ago
If you install python through nix, you get the nix version.

If you install python through apt, you get the ubuntu version.

1 comments

I get that part. I'm asking what the Nix version is like. Is it like the Ubuntu version with all the patches and backports and everything, or is it like the Arch (i.e. basically original unmodified) version?
Nix packages are typically close to upstream, but low-level packages sometimes have patches to make them more reproducible and deterministic, so that they work better with Nix's efforts for determinism and purely-functional packaging.

Nix packages are created from scratch, not copied from another distro. Nix is typically one of the most up-to-date distros: https://repology.org/

Okay thanks, so it sounds like I'll (roughly) end up with Arch (i.e. mostly-unmodified) whether I start on Ubuntu, Fedora, or whatever. I have another on that front: what about things like kernels? Don't those conflict with the OS?
If you install the "linux" package using nix on Debian, you get a directory in your nix store (the collection of "installed" packages) containing a bzImage, a System.map, and a `lib` directory containing all of the kernel modules. It would then be up to you to build an initrd and wire it into your bootloader, if that's what you wanted to do.

In other words, Nix packages are just files in their own special place on the disk (under /nix). If you want to configure binaries from those packages to run as daemons, or otherwise be wired into the system globally, that's up to you.

In fact, this is also true for the packages that you've "installed"! The nix package manager creates a package that represents your "user environment", and that package just merges all of the packages you installed using symlinks, and a symlink to that package is added to your $PATH.

"Just files" doesn't quite capture the complexity of the situation to me though. Say I happen to install package X via apt and Y via nix, and both of them depend on Z (in apt and nix respectively), and Z needs to bind to a port, then I imagine both will install but one of them will break, possibly including their dependents. Or if I install a package on Nix that expects a certain syscall that's not in the Ubuntu kernel yet (maybe like the recent /usr/bin/sleep issue with WSL), then that either breaks Nix or my ability to keep using an Ubuntu kernel. Right? And there are probably other things I'm just lacking the imagination for right now. But it seems to me there are all sorts of conflicts that can come up in practice. I've seen enough trainwrecks when upgrading even across OS versions that I have a hard time seeing how running 2 package managers can work on a single OS without breaking something?
> "Just files" doesn't quite capture the complexity of the situation to me though.

I think that's the root of the issue.

You seem to be somewhat confused about how Linux executes programs. An executable is just a file on the disk. It might be entirely self-sufficient or it might use libraries. Libraries are just files on the disk too (they end in .so.number where number is a version number). To load the libraries, when it starts a program, Linux first runs another executable called a dynamic linker (usually ld). Where the dynamic linker looks for the libraries files depends of its configuration. Ld will notably look into the paths listed in the LD_LIBRARY_PATH variable.

All of this has nothing to do with distributions. It's just how Linux works and will always be true. As long as you have all the so your executable need in a place where ld can find them, it will run.

Now, what a package manager does when you install a package is just putting all the files contained within it in the correct location, ensuring you will have installed the necessary shared libraries for the executable you want to run and setting up everything that might need to be setup.

You can manually add executables and so files as much as you like. The only issue you might encounter is using a location which is also used by a package. Depending of the package manager you use, that might either overwrite your modification or make the package installation fail.

While I have never used it, apparently Nix is well behaved and only install things into /nix so that shouldn't be an issue.

> Say I happen to install package X via apt and Y via nix, and both of them depend on Z (in apt and nix respectively)

That actually is impossible, Nix will only depend on packages in nix, and nothing else. So whatever you have installed won't affect it.

The important part of Nix on Linux is patchelf[1] basically binaries generated are processed by it, this rewrites elfs to link to libraries in the /nix/store

Regarding syscalls, if you use NixOS then you're tied to specific state of nixpkgs, which also dictates the kernel installed. So you shouldn't run into it. You probably might run if you install Nix on Ubuntu. I don't remember running into it, and I think it should be rare since linux ABI supposed to not break compatibility.

[1] https://github.com/NixOS/patchelf

> Say I happen to install package X via apt and Y via nix, and both of them depend on Z (in apt and nix respectively), and Z needs to bind to a port, then I imagine both will install but one of them will break.

When you install a package with apt, rpm, etc., it has the ability to run code at install time, create init scripts/systemd unit files, etc. When you install a package with Nix, it does not have that ability. So if you install Y via Nix, it will install Z via Nix, and Nix's Z will not be started automatically. You'll need to start it yourself (or Y will need to trigger it, when you run it, etc.)

If you also install X via apt and Z via apt, apt's Z will be started automatically, and will prevent Nix's Z from starting at the same time. You'll need to stop apt's Z.

Note that there's a spectrum here - Red Hat-based distros conventionally don't start software automatically when you install it, although they do leave the configuration in place for you to enable it (with chkconfig or something). Debian-based distros do. (While I am generally a Debian fan, this is one of the things I don't like about Debian ... possibly because I lost some mail once when I did "apt-get install exim" on a production server that had died, and a bunch of email that had been in other people's queues hit the default exim and then got bounces because I hadn't configured it yet.)

Another way of thinking about it is that there are two meanings of "install GRUB". One is that the GRUB commands are available for you to use. One is that your disk has GRUB in its boot sector. Arch, Debian, Red Hat, etc. all interpret "install GRUB" as doing both of these, but doing just the first one is valid, and then it's up to you to use the GRUB commands to put GRUB on the boot sector of whatever disk you want.

> Or if I install a package on Nix that expects a certain syscall that's not in the Ubuntu kernel yet (maybe like the recent /usr/bin/sleep issue with WSL), then that either breaks Nix or my ability to keep using an Ubuntu kernel. Right?

Yes. Nix won't install a new kernel for you, unless you're using NixOS.

(Technically, I suppose you can put a new kernel down on disk with Nix, but it won't install it in the sense of changing systemwide configuration.)

> I've seen enough trainwrecks when upgrading even across OS versions that I have a hard time seeing how running 2 package managers can work on a single OS without breaking something?

This is generally due to one of two things, both of which Nix sidesteps:

- There are incompatible updates to a file, e.g., you install "mawk," which provides /usr/bin/awk, but some other package expected that to be "gawk" and uses gawk-specific features. Nix doesn't have an equivalent to /usr/bin; there are no paths that are shared across packages. Each file is in a directory which corresponds to the identity of the one package (at one specific version) that provides it, and other packages bake in those dependencies. This is the fundamental cool thing about Nix.

- Systemwide changes when you install/remove stuff, like uninstalling syslogd shutting down your syslog daemon, installing a kernel changing the default kernel you'll boot into, etc. Installing a package in Nix doesn't have any effects beyond putting down files. The most Nix will do is keep a pointer (a "profile") to some set of stuff you're interested in (again, by exact identity). You can change that pointer, but there's nothing special about your particular pointer. If you point to a set of fewer things, other people can keep pointing to the things you no longer see. If you point to more things, that doesn't cause any code to run automatically.

Combined, this means that Nix stays out of the way of a traditional package manager. (Also, it means that you can set up your system so non-root users can install/remove things with Nix - you need to do some setup as root tp install Nix in the first place, but once it's there, users can't mess with each other.)

If you're familiar with virtualenvs etc., you can sort of think of it like that (although it's not a perfect metaphor) - you can install Python packages into a specific environment, but they don't get installed systemwide, and if you install, say, a web server (gunicorn, Flask, Django, etc.) into multiple virtualenvs, none of them are started automatically. You can't meaningfully install a kernel into a virtualenv (nothing stops someone from releasing a kernel on PyPI, but "installing" it will just download the file and put it somewhere and nothing else).

This does mean that the experience of using Nix is different from using a traditional package manager - you'll need to take care of starting the services you need, etc. Basically Nix reduces the scope of a package manager to say that running services isn't part of it, and then it does a better job of implementing that reduced scope. If you're a company like Shopify that is unlikely to be happy with the built-in web server that automatically starts when they "apt-get install apache2" that shows "Congratulations, you've installed a web server" to your customers, that's totally fine, you were going to do your own service management anyway.

Those are handled by NixOS - that's the purpose of NixOS, it was built on top of Nix explicitly to manage such things. You can read some about NixOS at https://nixos.org/nixos/about.html
And in particular, NixOS is a full OS, like Arch/Ubuntu/etc. You can't install NixOS side-by-side with Arch any more than you can install Arch side-by-side with Ubuntu. Nix-sans-NixOS is only the stuff that can be installed side-by-side with an existing OS - no service management, no kernels, etc.
Ah I see. yes as someone who contributes to nixpkgs, there are patches to use the /nix paths rather than the standard posix layout.

NixOS is not POSIX compliant and does not try to be.