nix icon indicating copy to clipboard operation
nix copied to clipboard

Steam Deck support

Open Atemu opened this issue 1 year ago • 51 comments

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.

Atemu avatar Oct 14 '22 17:10 Atemu

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

Enzime avatar Oct 22 '22 07:10 Enzime

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

deliciouslytyped avatar Oct 24 '22 15:10 deliciouslytyped

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.

Atemu avatar Oct 24 '22 16:10 Atemu

:+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.)

L-as avatar Oct 26 '22 11:10 L-as

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.

e-minguez avatar Dec 24 '22 06:12 e-minguez

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.

Atemu avatar Dec 24 '22 16:12 Atemu

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

e-minguez avatar Dec 24 '22 18:12 e-minguez

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. :)

Hoverbear avatar Jan 04 '23 15:01 Hoverbear

SteamOS 3.5 will have a /nix/ directory available. Currently the nix package is not pre-installed, however.

Nephyrin avatar Jun 23 '23 07:06 Nephyrin

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?

Scrumplex avatar Jun 23 '23 08:06 Scrumplex

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.

Atemu avatar Jun 23 '23 10:06 Atemu

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 avatar Jun 23 '23 18:06 Nephyrin

@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)

Hoverbear avatar Jun 23 '23 19:06 Hoverbear

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.

Atemu avatar Jun 23 '23 20:06 Atemu

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.

Ericson2314 avatar Jun 24 '23 17:06 Ericson2314

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.

Enzime avatar Jun 24 '23 23:06 Enzime

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.

Ericson2314 avatar Jun 25 '23 22:06 Ericson2314

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

Enzime avatar Jun 25 '23 23:06 Enzime

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.

Ericson2314 avatar Jun 25 '23 23:06 Ericson2314

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 avatar Jun 26 '23 00:06 Ericson2314

@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.

Atemu avatar Jun 26 '23 07:06 Atemu

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.

Nephyrin avatar Jun 26 '23 18:06 Nephyrin

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.

Ericson2314 avatar Jun 26 '23 20:06 Ericson2314

@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?

bertogg avatar Jun 27 '23 16:06 bertogg

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?

Atemu avatar Jun 27 '23 16:06 Atemu

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:

  1. Copy the files as you say and make sure that they are updated if Nix is upgraded.
  2. 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.

bertogg avatar Jun 27 '23 16:06 bertogg

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

Nephyrin avatar Jun 28 '23 18:06 Nephyrin

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?

alkazar avatar Jun 30 '23 12:06 alkazar

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!

SuperSandro2000 avatar Jun 30 '23 14:06 SuperSandro2000

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!

nckx avatar Jul 05 '23 13:07 nckx