Skip to main content

Multi-User Nix Installation

I tried installing Nix in multi-user mode earlier this year since it is now recommended. It installed without error, but the daemon would not start due to permissions issues. Since I did not need multi-user mode and prefer to minimize services on my system, I switched back to single-user mode. See the Uninstalling Multi-User Nix blog entry for details. Today, I am trying again!

I completely removed Nix from the host OS and ran the following command.

$ sh <(curl -L https://nixos.org/nix/install) --daemon

Installation proceeded the same as last time and finished without error. This time, the service is loaded without issue! I still have no idea what made the installation fail last time, but I am happy that it is working now.

$ sudo systemctl status nix-daemon.service
● nix-daemon.service - Nix Daemon
     Loaded: loaded (/etc/systemd/system/nix-daemon.service; linked; vendor preset: disabled)
     Active: active (running) since Wed 2022-04-06 06:12:37 JST; 42min ago
TriggeredBy: ● nix-daemon.socket
   Main PID: 109016 (nix-daemon)
      Tasks: 17 (limit: 14113)
     Memory: 3.8M
        CPU: 13ms
     CGroup: /system.slice/nix-daemon.service
             └─109016 nix-daemon --daemon

 4月 06 06:12:37 exponential systemd[1]: Started Nix Daemon.

My user (tcard) was not configured correctly, and it took me quite a bit of investigation to figure out why. I am deleting the investigation details from this blog entry, skipping directly to the explanation and resolution.

The installation sets up the following profiles.

  • /etc/bash.bashrc
  • /etc/bashrc
  • /etc/profile.d/nix.sh
  • /etc/zsh/zshrc (skipped because my system has no /etc/zsh directory)
  • /etc/zshrc

Different OSes/shells use different configuration files, and it is sort of dirty to pollute the /etc directory like this. They are all modified to contain code like the following.

if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
  . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi

The sourced script starts with the following code that ensures that it is only executed once. This is required since it prepends to the PATH environment variable, which should not be done more than once.

if [ -n "${__ETC_PROFILE_NIX_SOURCED:-}" ]; then return; fi
__ETC_PROFILE_NIX_SOURCED=1

My user ~/.profile configures my PATH from scratch. It does not use the default/system PATH, which contains directories that I do not want in my PATH. The following code is used to support both single-user and multi-user Nix.

if [ -e "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh" ]; then
  export NIX_REMOTE="daemon"
  source "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh"
elif [ -e "${HOME}/.nix-profile/etc/profile.d/nix.sh" ] ; then
  source "${HOME}/.nix-profile/etc/profile.d/nix.sh"
fi

My issue was that more than one of the above profiles in /etc were sourced when my shell started. The Nix environment was configured, and __ETC_PROFILE_NIX_SOURCED was set. My user ~/.profile later reset the PATH. The above code attempted to configure Nix, but it did not update the new PATH because __ETC_PROFILE_NIX_SOURCED was already set.

To resolve this issue, I reverted all /etc profile changes. In general, I greatly prefer this anyway, since it does not force all users to use Nix! Users can opt-in to using Nix by configuring their ~/.profile.

# mv /etc/bash.bashrc.backup-before-nix /etc/bash.bashrc
# rm /etc/bashrc
# rm /etc/profile.d/nix.sh
# rm /etc/zshrc

Now Nix is only configured in my ~/.profile, and it works. The user’s Nix profile, gcroots directory, etc. are all created automatically

$ nix-shell -p nix-info --run "nix-info -m"
 - system: `"x86_64-linux"`
 - host os: `Linux 5.17.1-arch1-1, Arch Linux, noversion, rolling`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.7.0`
 - channels(root): `"nixpkgs"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixpkgs`

With multi-user Nix, perhaps I need to use Nix with root as well… I configured /root/.profile and confirmed that it works.

$ sudo su -
# nix-shell -p nix-info --run "nix-info -m"
 - system: `"x86_64-linux"`
 - host os: `Linux 5.17.1-arch1-1, Arch Linux, noversion, rolling`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.7.0`
 - channels(root): `"nixpkgs"`
 - nixpkgs: `/root/.nix-defexpr/channels/nixpkgs`

Now that it is working, I will see if this helps with my possible cache issues. If things go well, I will go ahead and reconfigure my daily driver to use multi-user Nix as well.

Author

Travis Cardwell

Published

Tags
Related Blog Entries