Dear Nix/NixOS community!
I want to use Nix as a package manager for my user-local development environment. Ultimately, what I want to achieve is that I specify a list of packages that I want to have available, run some commands to ensure they are installed and their versions are frozen, and then have the ability to run some other commands to ensure that the paths to directories containing the relevant binaries are in my PATH variable. I would also like to be able to perform an upgrade of all the packages installed in this manner.
My main limitation is that I want to do this all on an HPC cluster, where my permissions are severely limited. As a result, I can’t perform a system-wide installation of Nix, as recommended here. Instead, I chose to use static build of Nix.
Below I describe what I tried, what works, what doesn’t work, and some questions that I have. Ultimately, I would kindly like to ask for your guidance as to which of the potential approaches I should pursue, and how I can make my experience more smooth and productive.
I started by retrieving a static build of Nix from this build, putting it into ~/.local/bin and doing chmod +x ~/.local/bin/nix. Then, I created a ~/.config/nix/nix.conf configuration file with the following contents:
extra-experimental-features = nix-command flakes
The first approach that I tried was to make use of Nix profiles functionality. Using yazi as an example package of interest, I ran nix profile add nixpkgs#yazi, which generated the following persistent output after a very long time cloning and unpacking git objects (please note that the cluster has file amount quotas and works with large file amounts inefficiently):
warning: '/nix/var/nix' does not exist, so Nix will use '/home/sprotser/.local/share/nix/root' as a chroot store
error: cannot read directory "/nix/store/v0sylxg2zng8qbwyfpyphnx8gsc5lzn8-yazi-25.5.31": No such file or directory
Indeed, /nix does not exist, but what is surprising is that attempt was made to access it despite an earlier claim that a user-local store will be used instead. After this command, my PATH variable is unchanged and yazi binary is not available. In my home directory there is .nix-profile, a broken symlink to /home/sprotser/.local/state/nix/profiles/profile. So this approach doesn’t seem to work. Did I do something wrong?
The second approach that I tried is to first run nix run nixpkgs#bashInteractive. After that, my shell prompt to longer shows my user name, showing I have no name! instead. However, both echo $USER and id show all the information as expected. In this shell, /nix exists and is owned by my username, and PATH variable is unchanged. Subsequent execution of nix profile add nixpkgs#yazi nixpkgs#btop completes almost immediately without output, with exit code of 0, but neither yazi nor btop are immediately runnable. However, .nix-profile is now a valid symlink to /home/sprotser/.local/state/nix/profiles/profile, and adding $HOME/.nix-profile/bin to PATH allows me to run both yazi and btop. Note that if I perform the same sequence of actions on another machine, a local virtual machine with a different locale (en_CA.UTF-8), upon running nix run nixpkgs#bashInteractive I get the following output:
bash: warning: setlocale: LC_CTYPE: cannot change locale (en_CA.UTF-8): No such file or directory
bash: warning: setlocale: LC_CTYPE: cannot change locale (en_CA.UTF-8): No such file or directory
bash: warning: setlocale: LC_COLLATE: cannot change locale (en_CA.UTF-8): No such file or directory
bash: warning: setlocale: LC_CTYPE: cannot change locale (en_CA.UTF-8): No such file or directory
bash: warning: setlocale: LC_CTYPE: cannot change locale (en_CA.UTF-8): No such file or directory
bash: warning: setlocale: LC_COLLATE: cannot change locale (en_CA.UTF-8): No such file or directory
So, this approach somewhat works, except for the fact that the shell fails to show my username in the prompt, doesn’t work well with non-en_US.UTF-8 locales, and the overall idea of using an intermediate shell feels a bit hacky. How do I fix the username and locale issues? Is this approach hacky, or is it perfectly fine?
The third approach that I tried is to exit the previously opened shell, create a flake directory, and in it a flake.nix file with the following contents:
{
description = "A very basic flake";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
};
outputs = { self, nixpkgs }: {
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
buildInputs = [
nixpkgs.legacyPackages.x86_64-linux.yazi
nixpkgs.legacyPackages.x86_64-linux.btop
];
};
};
}
and run nix develop. This command once again takes a long time to complete, processing git objects, and results in persistent output of
warning: creating lock file "/home/sprotser/flake/flake.lock":
• Added input 'nixpkgs':
'github:nixos/nixpkgs/5e2a59a5b1a82f89f2c7e598302a9cacebb72a67?narHash=sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs%3D' (2025-10-19)
error (ignored): package 'nixpkgs#bashInteractive' does not provide a 'bin/bash'
After that, I am in a bash shell, with my username correctly displayed in the prompt, /nix exists and displays as owned by my user id (but not my username as I got with Approach 2. Also, id now only shows my user id, but not my username, as before), and my PATH variable contains a lot of entries, each starting with /nix/store/, followed by what appears to be a build hash and package name, and ending with /bin. yazi and btop are available and run just fine. So this approach also works, however the error (ignored): package 'nixpkgs#bashInteractive' does not provide a 'bin/bash' confuses me. Why doesn’t it provide the requested binary? Should it? Why is this error ignored? Did I do something wrong? I am also confused by the fact that my username doesn’t show up in some places (ls -la /, which I used to check out the /nix directory, and id). How can I fix this? Is it okay that PATH variable now has a lot of entries, one for each package, including dependencies? I plan to install quite a lot of packages, will scaling be a problem?
Finally, after all these operations, ~/.local/share/nix/root/nix/store contains about 200k files, with 6h0sni7pw7gglk3cdml8zmbms1d5k3fq-source and 7agp54mgffm9m1wc1kgmkm37pvy18qhf-source subdirectories each containing about 80k files. Judging by their contents, they seem to be related to the main Nix metadata repository or something like that. Can they be safely removed or packed into archives, so that I don’t have the file amount problem? Under what conditions would I have to unpack them back from the archives? Also, how would I go about ensuring that software versions are frozen until I explicitly request an upgrade, for both approaches 2 and 3? How would I request such an upgrade, for both approaches?
I would greatly appreciate answers to the questions above, as well as any other guidance and insights. Thank you so much!