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.