nix icon indicating copy to clipboard operation
nix copied to clipboard

Document the installation prefix

Open fricklerhandwerk opened this issue 2 years ago • 9 comments

Problem

Many environment variables rely on a prefix that is not further explained, and it's not clear where it is defined and what value it has. In practice we observe it to be /nix.

Grepping the source one only finds one relevant occurrence in the Makefile, which defaults to /usr/local in the makefile, but this is just the location to place the build result in, and is set to $out in the Nix-based build.

Proposal

Document what prefix defaults to, and how and where it can be set.

Checklist

Priorities

Add :+1: to issues you find important.

fricklerhandwerk avatar Feb 07 '23 12:02 fricklerhandwerk

Might this be a more typical autotools+nixpkgs solution, that should be documented in Nixpkgs and referenced here?

Taking a minute, I could only find something about dontAddPrefix and the configure phase just above it. Nixpkgs doesn't seem to elaborate much on this; although maybe I missed one of the scattered reference bits that are grouped by technical class instead of domain topic.

roberth avatar Feb 07 '23 23:02 roberth

From multiple half-hearted attempts of navigating the code, it's not evident to me how and where that prefix is ever set to a non-default at all. It appears that building Nix as the installer would is defined outside this repository, but I'm probably missing something obvious.

fricklerhandwerk avatar Feb 08 '23 00:02 fricklerhandwerk

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/tweag-nix-dev-update-44/25546/1

nixos-discourse avatar Feb 17 '23 11:02 nixos-discourse

I'm running into this issue too. We would like to use google workstations and only the /home mount is persisted across restarts which means installing to /nix will not persist.

How can I set the prefix to e.g /home/user/nix ?

Edit:

Editing this line for single-user installs still fails https://github.com/NixOS/nix/blob/db3bf180a569cb20db42c5e4669d2277be6f46b6/scripts/install-nix-from-closure.sh#L7

/nix is hardcoded it seems, even for single-user installs. Probably a bind mount of the prefix to /nix/store should work, but that wouldn't work for users without admin rights...

Edit2:

So, it's probably because nix has hard coded paths to /nix/store and expects to find dependencies there.

user@michaels-workstation:~/nix/store/3wqasl97rjiza3vd7fxjnvli2w9l30mk-nix-2.17.0/bin$ ll
total 3752
dr-xr-xr-x 2 user user    4096 Jan  1  1970 ./
dr-xr-xr-x 7 user user    4096 Jan  1  1970 ../
-r-xr-xr-x 1 user user 3831976 Jan  1  1970 nix*
lrwxrwxrwx 1 user user       3 Jan  1  1970 nix-build -> nix*
lrwxrwxrwx 1 user user       3 Jan  1  1970 nix-channel -> nix*
lrwxrwxrwx 1 user user       3 Jan  1  1970 nix-collect-garbage -> nix*
lrwxrwxrwx 1 user user       3 Jan  1  1970 nix-copy-closure -> nix*
lrwxrwxrwx 1 user user       3 Jan  1  1970 nix-daemon -> nix*
lrwxrwxrwx 1 user user       3 Jan  1  1970 nix-env -> nix*
lrwxrwxrwx 1 user user       3 Jan  1  1970 nix-hash -> nix*
lrwxrwxrwx 1 user user       3 Jan  1  1970 nix-instantiate -> nix*
lrwxrwxrwx 1 user user       3 Jan  1  1970 nix-prefetch-url -> nix*
lrwxrwxrwx 1 user user       3 Jan  1  1970 nix-shell -> nix*
lrwxrwxrwx 1 user user       3 Jan  1  1970 nix-store -> nix*
user@michaels-workstation:~/nix/store/3wqasl97rjiza3vd7fxjnvli2w9l30mk-nix-2.17.0/bin$ ./nix-store
-bash: ./nix-store: No such file or directory
user@michaels-workstation:~/nix/store/3wqasl97rjiza3vd7fxjnvli2w9l30mk-nix-2.17.0/bin$ ldd nix
./nix: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./nix)
./nix: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by ./nix)
./nix: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by ./nix)
./nix: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by ./nix)
        linux-vdso.so.1 (0x00007ffd0eb63000)
        libsodium.so.23 => /lib/x86_64-linux-gnu/libsodium.so.23 (0x00007f069f5f3000)
        libeditline.so.1 => not found
        libnixexpr.so => not found
        libgc.so.1 => /lib/x86_64-linux-gnu/libgc.so.1 (0x00007f069f580000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f069f55b000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f069f555000)
        libnixmain.so => not found
        libnixfetchers.so => not found
        libnixstore.so => not found
        libnixutil.so => not found
        libnixcmd.so => not found
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f069f371000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f069f222000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f069f207000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f069f015000)
        /nix/store/4nlgxhb09sdr51nc9hdm8az5b08vzkgx-glibc-2.35-163/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f069f655000)

Edit 3:

sudo mkdir /nix
sudo mount --bind /home/user/nix /nix

Worked (unsurprisingly), but it's not a viable solution for users that don't have root privileges when installing nix.

michaelCTS avatar Aug 18 '23 09:08 michaelCTS

My understanding of a term "installation prefix" would be something like the ./configure --prefix option when building Nix from source. I don't think that's what most people would want to know about, unless they're packaging Nix as an FHS package in a traditional distro.

@michaelCTS brings up a similar question whose answer would include the storedir parameter (default: /nix/store). Iiuc, this is a parameter of LocalStore, so that you can use Nix to bootstrap a store with any storedir.

So, it's probably because nix has hard coded paths to /nix/store and expects to find dependencies there.

This project itself does not assume that it is built by Nix, and we generally don't hardcode the storedir. We do have defaults though, and some third party code might make the assumption. Those should be really minor issues that are easily fixed, so the only structural disadvantage is that you won't be able to reuse cache.nixos.org with it.

Furthermore it's possible to use Linux namespaces to provide a "virtual" store that resides in a different physical location such as your homedir, without having to change all those paths. This is the preferred solution because you can use cache.nixos.org with it. Linux namespaces are widely available nowadays. If you can run docker or podman, you can run Nix in this mode.

Apologies for the lack of concrete details; I hope this braindump is at least somewhat helpful until we resolve this issue properly.

Also did I just expand the scope of the issue?..

roberth avatar Aug 18 '23 10:08 roberth

I'm here because immutable ("atomic") Linux distros are using composefs making the root not writable and thus break the nix installer for Silverblue, Bluefin (and like) starting with F42.

Making the base prefix configurable would be great as it would help avoid such issues...

karypid avatar Mar 22 '25 20:03 karypid

@karypid without the default installation prefix, you won't be able to make use of caches like cache.nixos.org. Unless you want to run a build farm to support your Nix installation(s) this is not a solution. Any Linux system you fully control should be possible to configure to have a /nix directory, and that really is preferable.

roberth avatar Mar 31 '25 21:03 roberth

Apologies for the lack of concrete details; I hope this braindump is at least somewhat helpful until we resolve this issue properly.

Progress?

bam80 avatar May 19 '25 21:05 bam80

The build system was migrated to Meson, so the prefix is set with -Dprefix when building from source without using a pre-existing Nix, as noted in the reference manual.

The default store directory and a few other things can be be compiled in from the Nixpkgs build (used here, set from a freeform config value here). But as @roberth noted, this is probably not reasonable to customise (and the search for alternatives/workarounds is off topic for this issue).

For the next person going on a rabbit hole deep dive, trying to find the ground truth for various configuration constants: a lot of that is set in meson.build files and then used as compile-time constants. For example NIX_STORE_DIR:

  • https://github.com/NixOS/nix/blob/3e832b61ec2d4821f2846fbfc24f4440ac3f2f9e/src/libstore/meson.build#L10
  • https://github.com/NixOS/nix/blob/3e832b61ec2d4821f2846fbfc24f4440ac3f2f9e/src/libstore/meson.build#L249
  • https://github.com/NixOS/nix/blob/3e832b61ec2d4821f2846fbfc24f4440ac3f2f9e/src/libstore/globals.cc#L64 This is primarily used in the local store:
  • https://github.com/NixOS/nix/blob/3e832b61ec2d4821f2846fbfc24f4440ac3f2f9e/src/libstore/local-fs-store.cc#L11-L14
  • https://github.com/NixOS/nix/blob/3e832b61ec2d4821f2846fbfc24f4440ac3f2f9e/src/libstore/include/nix/store/local-fs-store.hh#L53-L57 ... wait, there's yet another default if rootDir is set, when the store's configuration is initialized, which could be always, I don't know. This settings code always confused the hell out of me.
  • https://github.com/NixOS/nix/blob/3e832b61ec2d4821f2846fbfc24f4440ac3f2f9e/src/libstore/local-fs-store.cc#L31-L33

fricklerhandwerk avatar Dec 10 '25 13:12 fricklerhandwerk