I installed nix on a server running Ubuntu 20.04, with a separate /nix bind-mount. But nix-daemon doesn’t start on boot and I have to do the following manually on each reboot:
I don’t know much about what nix installation does on non-nixos distros. But my best guess would be that some .service file is a symlink to some /nix/store path, and when systemd initializes during boot, this path doesn’t exist yet and therefore the symlink is dead and the service cannot be loaded.
You probably need to replace the service with another one that doesn’t reside in /nix/store. But then the question is if that will break during the next update or not.
Thanks for the suggestion. The nix-daemon.service and nix-daemon.sockets are indeed symlinked to /nix/store/<bla> and they probably are not available when systemd initializes.
But NixOS must be able to handle that somehow, given that /etc/systemd/system is a link to /etc/static/systemd/system which then links to /nix/store. How does NixOS handle this w/o problem?
I encountered this error trying to have a separate /nix partition on a Non-NixOS system. I didn’t find a nice way to fix it, but as a workaround I created a service that gets it started. This is the only mention of the issue I found, so I’m posting here in case anyone else finds it.
/etc/systemd/system/nix-kludge.service:
[Unit]
Description=Fix nix-daemon for separate /nix partition
RequiresMountsFor=/nix
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl daemon-reload
ExecStart=/usr/bin/systemctl start nix-daemon.socket
[Install]
WantedBy=multi-user.target
@samh That shouldn’t be necessary. The nix-daemon.socket unit should already have the equivalent of RequiresMountsFor=/nix/var/nix/daemon-socket/socket thanks to the default dependencies of socket units, and the nix-daemon.service unit that nix ships with already has:
@ElvishJerricco You are right that it has something like that. As far as I can tell, the problem is that the socket and service files are symbolic links:
Ah, right, I had forgotten the context of this thread Indeed that would be an issue. You could work around that by mounting /nix in your initramfs. How to do that depends on your distro, but on distros with systemd-in-initrd (e.g. fedora) you should be able to just add x-initrd.mount to the entry in /etc/fstab in your root fs, and the initrd will pick it up after mounting the root fs and before switching to the main system.
After some more searching I had found this blog post: Metamagical
It describes another way to fix it on Fedora (and derivatives), involving an /etc/fstab.sys file. I would have been satisfied with that, but the x-initrd.mount solution is simpler (and better documented compared to dracut and /etc/fstab.sys).
Would be nice to be able to systemctl edit nix-daemon and just put After=zfs-import.service or something to that effect, but because nix-daemon.service is a symlink it complains.
I supposed best to change the nix dataset to mountpoint=legacy and use fstab with the x-initrd trick from above.
That’s what I was saying – I tried systemctl edit and it gave an error. In my case looks like /nix didn’t get mounted at all this boot (which is unusual), which is probably why I had an error – the systemd service file is a symlink to /nix/var/nix/... which didn’t exist.
I’m not sure what happens if I had an override for a service file that was a broken symlink at the time it attempted to run, but I presume it wouldn’t work.
I am curious if this could be a cp instead of a symlink every time the link needs to update. This would prevent the issue with the link & the required mounts would mean it would be okay to run once everything is mounted.
this tbh, symlink to /nix inherently breaks if /nix is on a separate partition unless some extra tricks (like the x-initrd thing) are implemented by the user
I thought modern Ubuntu had transitioned to systemd-in-initrd, but it seems not. After a lot of trial and error I’ve figured out how to an in-initrd mount using the old initramfs-tools:
#!/bin/sh
# /etc/initramfs-tools/scripts/local-bottom/nixstore
set -e
case "${1}" in
prereqs)
exit 0
;;
esac
. /scripts/functions
. /scripts/local
log_begin_msg "Mounting nix store on /nix"
modprobe xfs
read_fstab_entry "/nix"
local_device_setup "$MNT_FSNAME" "nix store file system"
MNT_FSNAME="${DEV}"
if [ "$MNT_PASS" != 0 ]; then
checkfs "$MNT_FSNAME" "$MNT_DIR" "${MNT_TYPE}"
fi
if ! mount -t "${MNT_TYPE}" -o "${MNT_OPTS}" "$MNT_FSNAME" "${rootmnt}${MNT_DIR}"; then
panic "Failed to mount ${MNT_FSNAME} as $MNT_DIR file system."
fi
exit 0
#!/bin/sh
# /etc/initramfs-tools/hook/xfs
# We don't have any prerequirements
case $1 in
prereqs)
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
manual_add_modules xfs
copy_exec /sbin/fsck.xfs /sbin
Make sure you have an fstab entry for /nix and then update-initramfs -u -k $(uname -r). Change the xfs specific bits if you use a different filesystem - if you use the same filesystem as your root you can drop them entirely.
Ah, maybe it only does it for new installs? This machine has been upgraded from god-knows-what to 26.04, so perhaps there’s something I need to change.