nix
nix copied to clipboard
Steam Deck support
Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
It is currently not possible to install Nix on the Steam Deck using the regular installer due to its special immutable rootfs setup.
Valve has left us with quite some options however:
- We have superuser privileges
- /etc is permanently writeable, including fstab and systemd units
- Home is a bog standard read-write Unix filesystem (ext4) with quite a bit of space (depending on the model)
Describe the solution you'd like A clear and concise description of what you want to happen.
Ideally we could have Valve add an empty /nix/
directory to their SteamOS image. This way we could bind-mount a directory inside home onto /nix/
via a simple systemd mount unit and Nix could operate as usual.
IIRC we have tried to reach out to Apple regarding /nix
on macOS before but that wasn't very fruitful (heh).
Going by their past behaviour, I imagine Valve might be much more cooperative on such matters.
Perhaps we could even reach out to them in an "official" manner via the NixOS foundation.
The Guix folks might also have an interest in joining our request with one for a /gnu/
directory.
Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.
It is probably possible to achieve a rw /nix/
without the help of Valve using overlayfs, selectively mounting /usr/
etc. onto a custom tmpfs root or worse hacks but those might not even be possible or might be fragile.
Additional context Add any other context or screenshots about the feature request here.
The Steam Deck has limited possibilities in extending it with your own software due to its read-only rootfs. You can't just install Arch packages via pacman for instance.
Flatpak is installed and enabled by default and it covers GUI apps fairly well but it doesn't cover CLI apps at all.
Nix could really shine here.
I believe you can just run the following commands:
$ sudo steamos-readonly disable
$ sudo mkdir /nix
$ sudo steamos-readonly enable
However I believe this would get wiped out by Steam Deck updates, but it would probably be possible to write a systemd unit to set this up every boot
There are some usual approaches for cases where there are restrictions:
- something based on user namespaces
- proot
See e.g. https://nixos.wiki/wiki/Nix_Installation_Guide
Namespaced "solutions" are not good. They come with a whole range of issues. Most immediate of which is that you always need to enter a namespace before being able to run anything installed via Nix. This causes all kinds of headaches and that is not acceptable.
:+1: for the namespacing solution, I don't think there are much better solutions for this without heavily reworking how Nix works. (I can think of a few, but they are not trivial.)
https://determinate.systems/posts/nix-on-the-steam-deck
This (bind mounts and systemd units) is much more elegant than Valve adding an empty /nix dir for no reason.
I was looking into their solution just yesterday, great to have a write-up.
I don't think disabling the read-only root is in any way elegant but, done in a service like this, it is a quick and dirty solution that works.
They linked @Xe's article on how to install Tailscale on the Deck though where they describe using systemd-sysext to install the tailscale binary and apparently that works without "cracking the readonly seal". Not sure whether sysext could create /nix
for us though as it might be limited to stupid FHS dirs such as /usr
but, should that work, sysext would certainly be an elegant solution; without Valve even needing to lift a finger.
Man, it's so great to have a (mostly) bog-standard Linux with bog-standard systemd and all its features on a friggin console.
I was looking into their solution just yesterday, great to have a write-up.
I don't think disabling the read-only root is in any way elegant but, done in a service like this, it is a quick and dirty solution that works.
They linked @Xe's article on how to install Tailscale on the Deck though where they describe using systemd-sysext to install the tailscale binary and apparently that works without "cracking the readonly seal". Not sure whether sysext could create
/nix
for us though as it might be limited to stupid FHS dirs such as/usr
but, should that work, sysext would certainly be an elegant solution; without Valve even needing to lift a finger.
Man, it's so great to have a (mostly) bog-standard Linux with bog-standard systemd and all its features on a friggin console.
If they add FDE it would be awesome !
Edit: Link to the SteamOS repo issue asking for FDE https://github.com/ValveSoftware/SteamOS/issues/771
Unfortunately systemd-sysext
can't create a /nix
, I did experiment with this! Unfortunately making the root temporarily writable is the best option I've found. Certainly interested in finding a new idea. :)
SteamOS 3.5 will have a /nix/
directory available. Currently the nix package is not pre-installed, however.
SteamOS 3.5 will have a
/nix/
directory available. Currently the nix package is not pre-installed, however.
I assume this also means that it will be writable, then? Or will we need to mount our own partition there?
SteamOS 3.5 will have a
/nix/
directory available. Currently the nix package is not pre-installed, however.
That'd be amazing! Do you have a source for that?
Do they also ship /gnu/?
I assume this also means that it will be writable, then? Or will we need to mount our own partition there?
I doubt it'd be writeable but this frees us of having to create that directory in the read-only root which is the fragile part. We can bind-mount a rw directory on top at runtime without modifying the data on-disk.
That'd be amazing! Do you have a source for that?
Source is myself, being a SteamOS developer! It is configured via the holo-nix-offload
package, which you can peep the source of on the mirror at https://steamdeck-packages.steamos.cloud/archlinux-mirror/sources/jupiter-main/holo-nix-offload-0.1-1.src.tar.gz
If you try the (often unstable!) Main branch of SteamOS you can test it out.
Do they also ship /gnu/?
Not currently, but would be trivial to add
I assume this also means that it will be writable, then? Or will we need to mount our own partition there?
It is currently bind-mounted to the data partition at /home/.steamos/offload/nix/
along with other 'offload' directories that are independent of OS update (unlike the small/volaile /var
which undergoes a selective migration on update).
I would also be interested in opinions on having the nix arch package installed by default in SteamOS builds. SteamOS tends to ship a minimal set of OS packages and rebase on arch with month(s) of latency, so it could be detrimental 'helpfully' pre-ship a potentially-old Nix binary. Does Nix have a good self-replacing-with-nixpkgs-nix story in that case?
@Nephyrin You might be able to ship a minimal nix which users could nix upgrade-nix
to get a recent copy?
A side note, we added support for the new /home/.steamos/offload/nix
recently in our nix-installer
crate (https://github.com/DeterminateSystems/nix-installer/pull/495) and it works really great! We did have an issue someone raised about wanting to use nix
from an sdcard though (https://github.com/DeterminateSystems/nix-installer/issues/509), so we may need to tweak support. Feel free to try it out (off the main
branch at this moment)
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix/branch/main | sh -s -- install
(I should note if you do, to uninstall before rolling back to an old SteamOS branch. Things will break)
Source is myself, being a SteamOS developer!
Oh! Well, that's a rather good source then :D
Thanks a bunch for considering us <3
If you try the (often unstable!) Main branch of SteamOS you can test it out.
I'm personally short in time for the next ~month but I'm sure others will try it on their Decks.
Not currently, but would be trivial to add
I'm sure the Guix folks would appreciate that! Much of the same that applies to us applies to them aswell as the projects are quite similar on a fundamental level.
It is currently bind-mounted to the data partition at
/home/.steamos/offload/nix/
along with other 'offload' directories that are independent of OS update
That sounds like a sane strategy. It'd be great if the user could choose where the offload directory is located physically like @Hoverbear mentioned; some users might want Nix on the SD card.
Though technical users could of course just set up fstab/mount units to accommodate that and Nix users are very likely to be technical.
I would also be interested in opinions on having the nix arch package installed by default in SteamOS builds.
This could be done but I don't think it's necessary. Unless you plan to make use of Nix within SteamOS, I don't think every SteamOS user needs Nix. The Nix package itself has a significant size and pulls in quite a few dependencies, some of which even most Nix users do not need (such as the AWS SDK).
The ones who do need/want Nix will be able to install it themselves just fine as long as /nix/
exists and /etc
can be modified for environment glue.
Nix shouldn't really be managed by another package manager anyways IMHO; it's its own package manager afterall and stays out of the way of the "host" system as much as it can.
SteamOS tends to ship a minimal set of OS packages and rebase on arch with month(s) of latency, so it could be detrimental 'helpfully' pre-ship a potentially-old Nix binary.
I don't think that'd cause any real issues. Nix is quite conservative when it comes to compatibility and stays backwards compatible. You can still eval the current Nixpkgs with a Nix build from 2019 and I'm sure even earlier builds work too.
Just a few months wouldn't be anything to be concerned about, other than security etc. which always applies.
Oh good. I've been hoping Nix would show up on Valve's radar for a very long time.
Does Nix have a good self-replacing-with-nixpkgs-nix story in that case?
Potentially :). There is an experimental nix upgrade-nix
command, for example.
You can ship a single statically linked binary of Nix and it works, so in some sense this is thankfully not too hard a problem. But for configuring the system to be able to use all of Nix's features, it gets harder. Thankfully, there are new/upcoming features like the auto-allocate-uids
configuration option that obviate needing to configure the underlying system for such features; I certainly hope we can continue down that route so installing Nix becomes successively more trivial.
@Nephyrin I am happy to answer any further questions / otherwise assist in any way I can. I am sure others from the Nix team besides myself would similarly be interested too.
As a Steam Deck owner I would love to see Nix pre installed, I think there will definitely be utility as users can run programs without having to install them. The good thing about SteamOS being based on Arch is they can use the Arch Nix package as an easy bootstrap.
I just tested Nix on Arch, and I agree one potential blocker would be that Nix pulls in AWS SDK as a dependency which is 500MB, the rest of Nix and its dependencies are only like 100MB. I think it would be worth making AWS SDK an optional dependency as from what I saw it was only used for S3 binary stores, and it would reduce the upfront storage cost for users.
Another issue is that nix upgrade-nix
only works when Nix is installed from a profile, whereas the Arch package installs it to /usr/bin
and the Arch Nix Daemon service uses /usr/bin/nix
. I’m not sure what the best solution for improving the upgrade-nix
on Arch (and SteamOS) is.
If there’s interest on the Nix team side, I’d be happy to work on these issues.
The AWS SDK is already an optional dependency, actually. See the various ENABLE_S3
in the Nix codebase.
I don't think it makes sense for Nix to know how to uninstall the Arch Nix package, but any version of Nix is capable of installing Nix via Nix, and we could try to somehow make sure the Arch is "shadowed" the newly installed Nix (e.g. PATH
order and whatnot).
Still, such shadowing is a bit fragile. Do you have a link to the Arch Nix package? I'd be curious to see what it does and doesn't do. That will help inform how much value we get out of it versus something else.
Oh, I totally missed that, I wonder if people would be willing to change the default to false to reduce the closure size.
Here's the source files for the Nix package:
https://gitlab.archlinux.org/archlinux/packaging/packages/nix
Thanks @Enzime.
I'll go through the files in here
- https://gitlab.archlinux.org/archlinux/packaging/packages/nix/-/blob/main/nix.conf
Needed for build-users-group
today. Could do auto-allocate-uids
instead, but still need file for that.
Easy to create /etc/nix/nix.conf
ourselves, however.
- https://gitlab.archlinux.org/archlinux/packaging/packages/nix/-/blob/main/sysusers.conf
Setting up build users and groups. Can drop entirely with auto-allocate-uids
.
- https://gitlab.archlinux.org/archlinux/packaging/packages/nix/-/blob/main/tmpfiles.conf
Setting up some state directories. Still need those directories, but I think can be done by Nix itself on startup. File shouldn't be needed.
- https://gitlab.archlinux.org/archlinux/packaging/packages/nix/-/blob/main/user.environment.conf
Unneeded. The users of Nix can set PATH
themselves. NIX_REMOTE=daemon
will be auto-detected. NIX_PATH
is purely optional, can also be set by users if they want it.
- https://gitlab.archlinux.org/archlinux/packaging/packages/nix/-/blob/main/user.tmpfiles.conf
Unneeded. Since Nix 2.15 all of this stuff is within the user's home directory, and will be created as needed on demand.
- https://gitlab.archlinux.org/archlinux/packaging/packages/nix/-/blob/main/PKGBUILD
Main file. Nothing that interesting but installing the other files.
So in conclusion, I don't think there is much extra value being gotten from the Arch Nix installer. The main point of system integration we don't currently have a replacement for is integrating with the systemd configuration, but with https://github.com/NixOS/nix/pull/5380 even the Nix daemon can just be run as non-root, making the systemd configuration a good bit lower stakes.
@Ericson2314 just so there's no misunderstanding, we can freely modify /etc/
on SteamOS. All the stuff the regular Nix installer configures (users, shells, systemd units, nix.conf etc.) just works like it does everywhere else. The only thing we're unable to do (without disabling readonly) is the creation of /nix/
which apparently SteamOS now does for us.
I think the benefit of including a pre-installed nix binary would be the ability to simply start using nix without fetching a web installer, but as the self-upgrade/replacing-system-binary story isn't great as-is my feeling is it wouldn't be helpful as a whole. (I also wasn't able to get the Arch packaging of Nix working on my system easily here, running into search path errors and requiring fiddling with NIX_PATH
, I get the feeling using the official installer is much better tested ground)
For Steam Deck, Perhaps bundling some kind of nix-install
script that embeds the curl web.site | sh -s ...
fun while maintaining a chain of trust would be the way to go?
I see the official https://nixos.org/nix/install script already includes some hash checks and may fit the bill there as-is -- or we could add another layer of fetching the 'current' install script with a signature check, depending on how stable the installer is.
Yes chain of trusts with installers can definitely work.
Also to @Atemu's point, it is precisely because the Arch installer could do arbitrary things that commands like nix upgrade-nix
are wary of clobbering it. A pre-install that puts nix in /nix/store/...
not /usr/bin
will not trigger those cautious aborts, and self-upgrade path works just fine in that case.
In a way, these are not that different. A signed/trampolined installer or pre-installed Nix without involving Arch both lead to basically the same place, and if a user wants to do a self-upgrade to a newer version of Nix form there, that is the same process too.
@Atemu
we can freely modify
/etc/
on SteamOS. All the stuff the regular Nix installer configures (users, shells, systemd units, nix.conf etc.) just works like it does everywhere else.
I think that there's an additional problem: the installer script does put the systemd unit files in /etc/systemd
, but they are symlinks to the actual files under /nix
. Those files are however not available until systemd mounts /nix
, so the symlinks are dead and therefore ignored when systemd reads its configuration at boot time (it does work if you reload the systemd configuration after /nix
is mounted).
This does not affect single-user mode as far as I can tell, and Nix seems to work just fine in that scenario.
However I suppose that it would also be nice if both the root
and deck
users can run software installed with Nix. Is that only possible if Nix is running in multi-user mode, or is there any other alternative?
Thank you for pointing that out @bertogg. That would indeed not work.
Although I see little reason for root to run nix tools, multi-user Nix is the only well supported option, so we do need multi-user.
NixOS gets around this issue by mounting /nix
in the initrd IIRC but I'm not familiar with how that's done in the new systemd initrd.
A simple way around this issue would be to copy the file rather than symlinking. A similar thing is done on macOS for the org.nixos.nix-daemon.plist
because /nix
is mounted separately too. I'm not sure how nix upgrade-nix
works in this case though as it must have a hook to update the file?
The general issue would be "Support installations where /nix
is not in the root filesystem", as this could conceivably happen anywhere.
At first sight I can also think of two possible solutions:
- Copy the files as you say and make sure that they are updated if Nix is upgraded.
- Reload the systemd configuration (the solution proposed in this post does that), but that might be tricky to implement in a generic way (i.e. not only for SteamOS). I also don't like the idea of a systemd unit running
systemctl daemon-reload
, maybe it's supported but intuitively it feels hackish and error prone.
Do they also ship /gnu/?
A quick check here shows that the guix installer needs a bit more interaction with the system than just a /gnu
mount available, so it's not clear if this would be useful standalone. If any guix folks are interested in pushing on this let us know
ChimeraOS dev here. This is a really interesting idea. Would it be helpful to mount /nix
as a read-write BTRFS subvolume? We do this for /home
and /var
already.
ChimeraOS is also an immutable OS based on Arch, but pushes updates more frequently. Usually once a month. In such a case, would it be useful to include the nix
Arch package? Or would it still get in the way?
gitlab.archlinux.org/archlinux/packaging/packages/nix/-/blob/main/nix.conf
Since contributing to arch is not as easy as just opening a MR on their GitLab can someone remove the line suggesting that disabling sandbox is a good idea? Thanks!
A quick check here shows that the guix installer needs a bit more interaction with the system than just a
/gnu
mount available, so it's not clear if this would be useful standalone.
Which interaction(s) in particular are problematic?
We're talking about guix-install.sh, right?
If any guix folks are interested in pushing on this let us know
Nice. Have you advertised this offer anywhere else? You're very welcome to post to guix-devel @ gnu.org.
If you don't have time, I'd be happy to share a link to this discussion.
I'm not much of a gamer and don't own a Steam Deck, but I do think they're awesome and want to see them succeed in their current, open form. Thanks for being part of the community!