Skip to content

Instantly share code, notes, and snippets.

@matthewpi
Last active April 17, 2024 15:47
Show Gist options
  • Star 38 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save matthewpi/08c3d652e7879e4c4c30bead7021ff73 to your computer and use it in GitHub Desktop.
Save matthewpi/08c3d652e7879e4c4c30bead7021ff73 to your computer and use it in GitHub Desktop.
Nix on Fedora

NixOS on Fedora

Please note that these instructions are not offically supported or condoned by Nix and are not guaranteed to always work, but from my testing everything seems to work perfectly fine.

These steps may not be required if NixOS/nix#2374 is resolved.

SELinux

These commands are required for both Fedora Workstation and Fedora Silverblue

sudo semanage fcontext -a -t etc_t '/nix/store/[^/]+/etc(/.*)?'
sudo semanage fcontext -a -t lib_t '/nix/store/[^/]+/lib(/.*)?'
sudo semanage fcontext -a -t systemd_unit_file_t '/nix/store/[^/]+/lib/systemd/system(/.*)?'
sudo semanage fcontext -a -t man_t '/nix/store/[^/]+/man(/.*)?'
sudo semanage fcontext -a -t bin_t '/nix/store/[^/]+/s?bin(/.*)?'
sudo semanage fcontext -a -t usr_t '/nix/store/[^/]+/share(/.*)?'
sudo semanage fcontext -a -t var_run_t '/nix/var/nix/daemon-socket(/.*)?'
sudo semanage fcontext -a -t usr_t '/nix/var/nix/profiles(/per-user/[^/]+)?/[^/]+'

If you are on Fedora Workstation, skip past the Fedora Silverblue section down to Install Nix

Fedora Silverblue

If you are running Fedora Silverblue, you will need to follow these extra steps.

Create the nix directory in a persistent location

sudo mkdir /var/nix

SELinux

You will want to the SELinux contexts for the mounted directory paths as well, it seems to help avoid some weird issues periodically.

sudo semanage fcontext -a -t etc_t '/var/nix/store/[^/]+/etc(/.*)?'
sudo semanage fcontext -a -t lib_t '/var/nix/store/[^/]+/lib(/.*)?'
sudo semanage fcontext -a -t systemd_unit_file_t '/var/nix/store/[^/]+/lib/systemd/system(/.*)?'
sudo semanage fcontext -a -t man_t '/var/nix/store/[^/]+/man(/.*)?'
sudo semanage fcontext -a -t bin_t '/var/nix/store/[^/]+/s?bin(/.*)?'
sudo semanage fcontext -a -t usr_t '/var/nix/store/[^/]+/share(/.*)?'
sudo semanage fcontext -a -t var_run_t '/var/nix/var/nix/daemon-socket(/.*)?'
sudo semanage fcontext -a -t usr_t '/var/nix/var/nix/profiles(/per-user/[^/]+)?/[^/]+'

/etc/systemd/system/mkdir-rootfs@.service

[Unit]
Description=Enable mount points in / for ostree
ConditionPathExists=!%f
DefaultDependencies=no
Requires=local-fs-pre.target
After=local-fs-pre.target

[Service]
Type=oneshot
ExecStartPre=chattr -i /
ExecStart=mkdir -p '%f'
ExecStopPost=chattr +i /

/etc/systemd/system/nix.mount

[Unit]
Description=Nix Package Manager
DefaultDependencies=no
After=mkdir-rootfs@nix.service
Wants=mkdir-rootfs@nix.service
Before=sockets.target
After=ostree-remount.service
BindsTo=var.mount

[Mount]
What=/var/nix
Where=/nix
Options=bind
Type=none

Enable and mount the nix mount and reset the SELinux context.

# Ensure systemd picks up the newly created units
sudo systemctl daemon-reload
# Enable the nix mount on boot.
sudo systemctl enable nix.mount
# Mount the nix mount now.
sudo systemctl start nix.mount
# R = recurse, F = full context (not just target)
sudo restorecon -RF /nix

Install Nix

After you have configured SELinux (and if you are on Silverblue, configured a /nix mount), it's time to install Nix.

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

If you are running Fedora Workstation, you are now ready to rock! If you are running Fedora Silverblue, you will need to do some additional configuration.

Fedora Silverblue

If you are running Fedora Silverblue, you will need to run these additional steps. Most likely the installation errored out while setting up systemd. SELinux on Silverblue prevents systemd from loading the units linked by Nix, while the best solution would be to add a policy or package Nix as an RPM, we will just manually copy the units ourselves.

TODO: Find a way to link the units, that way whenever Nix is updated you don't need to manually edit or copy the units.

# Remove the linked services
sudo rm -f /etc/systemd/system/nix-daemon.{service,socket}
# Manually copy the services
sudo cp /var/nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.{service,socket} /etc/systemd/system/
# Ensure systemd picks up the newly created units
sudo systemctl daemon-reload
# Start (and enable) the nix-daemon socket
sudo systemctl enable --now nix-daemon.socket

Optionally, you may manually modify the nix-daemon units to add a bind to nix.mount to ensure the units activate and deactivate properly if the mount fails or if the mount is unmounted while the daemon is running. Place the following at the bottom of the [Unit] section in both the nix-daemon.socket and nix-daemon.service units.

After=nix.mount
BindsTo=nix.mount

You have just installed Nix and should be ready to rock!

NOTE: the nix-daemon.socket unit will automatically start nix-daemon.service whenever it is needed, there is no need to enable or manually start the service.

@matthewpi
Copy link
Author

Thank you. It helped me a lot. I have 2 suggestion:

  1. Better to create nix directory under /var/lib/nix for silverblue. Contaners & flatpaks there too.
  2. Maybe you can consider to add to this howto also single user install?
  1. I'm aware of the purpose of the /var/lib directory, is there any specific reason to move the nix directory there other then for consistency?
  2. Pretty sure a single-user install in regards to this manual is pretty similar. You will likely still need or want the SELinux policies and on Silverblue you will definitely still need the mount. It seems the main difference will be how nix-daemon works. I don't currently have a way to easily and cleanly test the single-user installation, so I probably won't add anything about that to this document unless someone else is able to explain how.

Also please look back over the manual as I recently updated it to fix some issues I was having on reboot.

@queeup
Copy link

queeup commented Jun 30, 2022

  1. /var/lib/nix for consistency and also if you are manually create btrfs subvolume for that directory to avoid nix packages to enter your snapshots. Anyways snapshots are not useful on silverblue.
  2. I tested it on virtual machine and I success with some changes from your how to.

For single user install I change this things:

  • Change nix directory owner to your user
    sudo mkdir /var/nix
    sudo chown $USER:$USER /var/nix
  • Get rid of Before=nix-daemon.socket line from nix.mount. Single user install is not installing nix-daemon.{socket,service} files.
  • Use install script with --no-daemon instead of --daemon.
    sh <(curl -L https://nixos.org/nix/install) --no-daemon

Note: If you are changed your selinux state to permissive you can skip that extra selinux steps you can skip semanage commands.

SELinux on Silverblue prevents systemd from loading the units linked by Nix, while the best solution would be to add a policy or package Nix as an RPM

Hope to see RPM package on the official repo.

Also please look back over the manual as I recently updated it to fix some issues I was having on reboot.

I bookmarked and stared this howto. I will check it time to time.

@jcdickinson
Copy link

Thanks for the awesome tutorial! I have distilled this into this script: https://gitlab.com/jcdickinson/nix/-/blob/main/install-fedora and these supporting files: https://gitlab.com/jcdickinson/nix/-/tree/main/install.

Fedora Silverblue, you will need to run these additional steps. Most likely the installation errored out while setting up systemd. SELinux on Silverblue prevents systemd from loading the units linked by Nix, while the best solution would be to add a policy or package Nix as an RPM, we will just manually copy the units ourselves.

Do you know what the SELinux configuration would be? Maybe I can get this all put together nicely and contributed upstream.

@dnkmmr69420
Copy link

this is not working for me. I am using silverblue and I tested this in a silverblue vm. when I ran sudo cp /var/nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.{service,socket} /etc/systemd/system/ nix-daemon in the nix directory does not exist. any workarounds?

@dnkmmr69420
Copy link

I made a modified version of this guide here and I tested it several times and it is working

@kleino
Copy link

kleino commented Mar 20, 2024

I tried out the steps here, for Fedora Workstation 39, I got a Nix does not work with selinux enabled yet! error from the nix-installer.

@biscotty666
Copy link

This did not work for me either, with the error message reported above.

@jcdickinson
Copy link

Just use the semi-official installer folks: https://github.com/nix-community/nix-installers

@biscotty666
Copy link

Thank you very much for the link. I will use it in the future.

I ended up successfully using https://github.com/dnkmmr69420/nix-installer-scripts, which was recommended here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment