Play proton game from systemd-nspawn container

This solution was the result of a conversation between me and Gemini. It has been tested and seems to be a good approach.

I do this for isolate game environments and improve security.

Game run in container, but display on host.

Steps:

create a systemd-nspawn container

Please refer guides on internet. I recommend you run a unprivileged container (Enable PrivateUsers) and enable security option as many as possible.

Must:

  • bind /dev/dri into container, and ensure users in container can access dri devices (you can do this by acl)
  • Bind another custom path into container. we need to share gamescope files from host to container, for example, in this topic I use path /share-with-container/ both on host and container

Tip: you can run a headless desktop in container, for example: sway.

Install proton games in container

You can use some launchers to help you setup proton and games, I use Faugus.

Run

on host (notes that I assume you have already run a desktop on host, its socket is /run/user/1000/wayland-1):

touch /share-with-container/tmp/.X{0..10}-lock

systemd-run --user --wait --pty -p "BindPaths=/share-with-container/tmp:/tmp" \
-E XDG_RUNTIME_DIR=/share-with-container/runtime \
-E WAYLAND_DISPLAY=/run/user/1000/wayland-1 \
gamescope \
--expose-wayland -W 2560 -H 1422 --borderless --force-windows-fullscreen -- sleep infinity

systemd-run --user --wait -p "BindPaths=/share-with-container/tmp:/tmp" \
-E DISPLAY=:11 \
xhost '+'

in container (replace ... part to your game launch command):

systemd-run --user --wait -p "BindPaths=/share-with-container/tmp:/tmp" \
-E DISPLAY=:11 \
-E WAYLAND_DISPLAY=/share-with-container/runtime/gamescope-0 \
...

Audio share

I use pipewire netjack2 to send audio from container to host.

The games I have tested

  • red alert 3
  • gta sa
  • Assassin’s Creed 2