This setup allows you to start a single Sway remote desktop session on a virtual display directly from Moonlight by sending the Wake PC request, waiting a few seconds and connecting to a fresh new desktop. Or you can just have a desktop running constantly in the background. This requires no dummy plugs or input devices attached to the host, but will also allow you to sometimes log in locally and and have that session available on sunshine too. Some of this stuff probably also works with other wlroots-based compositors with small changes.
I'm assuming you've first read and memorized the Sunshine documentation, it probably includes some very important stuff I didn't put here. The stuff about udev rules is probably important, cap_sys_admin not so much.
This is not supposed to be a complete guide to set up headless sunshine streaming and I assume you already know how to set up a sway desktop with hardware acceleration, but some (Arch) packages you probably also want are:
sway swaybg foot wmenu nvidia libvdpau libva-nvidia-driver cuda egl-wayland libva-utils nvtop pavucontrol pipewire-pulse steam gamescope
Obviously you'll need sunshine
from the official repository, or maybe sunshine-git
from AUR. The sunshine settings I have left completely as defaults, which probably makes it use wlroots
for capture and nvenc
for encoding.
Other stuff you probably need to do:
# no idea if all of these are needed
sudo usermod -a -G users,wheel,audio,video,input dregu
# start service on demand with WoL ping
sudo systemctl enable --now sway-sunshine.socket
# or if you don't want the WoL stuff
sudo systemctl enable --now sway-sunshine.service
Because the systemd service runs a login session in tty1 as a workaround to get input working without actually logging in, this is only meant for remote use. That said you can also log in to tty1 locally, run sway
and connect to that session with moonlight, but only when the headless one is not running.
These silly input hacks are needed because there's currently no easier way to just assign the virtual input devices to a headless sway process. (Please correct me if I'm wrong, I'd really like to just use libseat or something properly.) Other hack that worked was setting up console autologin for the user running the sway service, or just running sway from tty1, but that's not very on demand and servery any more.
To top it off add a sunshine prep command /bin/bash /home/dregu/.config/sway/scripts/sway-sunshine.sh
for Desktop to match the client resolution automatically.