Webux Lab

By Studio Webux

Setup Sunshine, Moonlight, Nvidia on Fedora 40

TG
Tommy Gingras Studio Webux 2025-04-01

Sunshine X Moonlight on Fedora 40

Bundle

Introduction

I am far from being an expert in any of the following.

I read a bunch of GitHub issues, tutorials, and random posts.

I think there are many ways to achieve the same thing, but I’m still not satisfied with the outcome. I’ll need to read more to fully understand “X multiseat” and “virtual inputs.”

Anyway, this post is just my notes on how I was able to do the following:

These notes are probably not copy-paste ready, as setups may differ slightly.

Prerequisites

sudo dnf install nvidia-vaapi-driver libva-utils vdpauinfo
sudo dnf install xorg-x11-drv-nvidia-cuda-libs xorg-x11-drv-dummy
sudo dnf copr enable lizardbyte/beta
sudo dnf install Sunshine

You might need to install other dependencies depending on your machine’s current state (I already had a couple of things installed from other projects and tests).

Linux Setup

I’m not convinced this setup is considered secure, so use it at your own risk. This machine is not exposed to the internet (I saw a few posts where people exposed their machines. I use WireGuard for that).

Reference: Xorg.wrap

This line allows everything to work (meaning that using SSH, you’ll be able to spin up a screen and start Sunshine):

sudo echo "allowed_users=anybody" | tee -a /etc/X11/Xwrapper.config

I had to do this a couple of times, but I don’t think it’s required every time:

lsmod | grep uinput
# If uinput is missing, you have to load it manually.
sudo modprobe uinput

File permissions

This part was tricky, and again, I’m not sure how secure it is. I’m also not 100% convinced it’s required in all cases.

sudo usermod -aG video $USER
sudo usermod -aG input $USER
sudo setfacl -m g:input:rw /dev/uinput
sudo setfacl -m g:input:rw /dev/uhid

Note: I do not make these configurations persistent, and that’s intentional. You can make them persistent if needed.

Xorg Setup

This part is still pretty obscure to me…

I tested a couple of things but didn’t cover all edge cases.

The config I got working—with and without a physical screen (or dummy dongle) connected—is the following:

Note: If you reboot your machine and lose video output, it’s very likely caused by this file.

Reference: remote-ssh-headless-sunshine-setup

sudo vi /etc/X11/xorg.dummy.conf
Section "ServerLayout"
Identifier "TwinLayout"
Screen 0 "metaScreen" 0 0
EndSection

Section "Monitor"
Identifier "Monitor0"
Option "Enable" "true"
EndSection

Section "Device"
Identifier "Card0"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BusID       "PCI:8:0:0"
Option "MetaModes" "1920x1080"
Option "ConnectedMonitor" "DP-0"
Option "ModeValidation" "NoDFPNativeResolutionCheck,NoVirtualSizeCheck,NoMaxPClkCheck,NoHorizSyncCheck,NoVertRefreshCheck,NoWidthAlignmentCheck"
EndSection

Section "Screen"
Identifier "metaScreen"
Device "Card0"
Monitor "Monitor0"
DefaultDepth 24
Option "TwinView" "True"
SubSection "Display"
Modes "1920x1080"
EndSubSection
EndSection

PS5 Controller

In Sunshine’s web UI, I had to force Xbox Controller emulation; otherwise, the PS5 mapping in Moonlight was incorrect.

Launch everything

export DISPLAY=:99
Xorg :99 -config 20-dummy.conf -keeptty
sunshine &
gnome-session &

And when you are done:

kill %1

Run jobs, and the first PID (1) represents the Xorg process. The other processes will be terminated automatically.

Extra notes

Errors that I saw often

(EE)
Fatal server error:
(EE) no screens found(EE)
(EE)
Please consult the The X.Org Foundation support
	 at http://wiki.x.org
 for help.
(EE) Please also check the log file at "/var/log/Xorg.99.log" for additional information.
(EE)
(EE) Server terminated with error (1). Closing log file.

The error can be anything… but the /var/log/Xorg.99.log contains relevant information. I noticed that I needed to move the config file (as mentioned above) and avoid using unusual configurations.

[2025-04-01 23:48:25.324]: Info: Sunshine version: v2025.331.200502
[2025-04-01 23:48:25.324]: Info: Package Publisher: LizardByte
[2025-04-01 23:48:25.324]: Info: Publisher Website: https://app.lizardbyte.dev
[2025-04-01 23:48:25.324]: Info: Get support: https://app.lizardbyte.dev/support
[2025-04-01 23:48:25.324]: Info: config: 'nvenc_twopass' = full_res
[2025-04-01 23:48:25.324]: Info: config: 'nvenc_preset' = 1
[2025-04-01 23:48:25.324]: Info: config: 'native_pen_touch' = disabled
[2025-04-01 23:48:25.324]: Info: config: 'gamepad' = xone
[2025-04-01 23:48:25.326]: Warning: Failed to create system tray
[2025-04-01 23:48:25.392]: Error: Failed to create session:
[2025-04-01 23:48:25.392]: Error: Couldn't open: /dev/dri/card1: Permission denied
[2025-04-01 23:48:25.392]: Error: Environment variable WAYLAND_DISPLAY has not been defined
[2025-04-01 23:48:25.392]: Info: Detecting displays
[2025-04-01 23:48:25.392]: Error: Unable to initialize capture method
[2025-04-01 23:48:25.392]: Error: Platform failed to initialize
[2025-04-01 23:48:25.492]: Info: // Testing for available encoders, this may generate errors. You can safely ignore those errors. //
[2025-04-01 23:48:25.492]: Info: Trying encoder [nvenc]
[2025-04-01 23:48:25.892]: Info: Encoder [nvenc] failed
[2025-04-01 23:48:25.892]: Info: Trying encoder [vaapi]
[2025-04-01 23:48:26.292]: Info: Encoder [vaapi] failed
[2025-04-01 23:48:26.292]: Info: Trying encoder [software]
[2025-04-01 23:48:26.692]: Info: Encoder [software] failed
[2025-04-01 23:48:26.692]: Fatal: Unable to find display or encoder during startup.
[2025-04-01 23:48:26.692]: Fatal: Please check that a display is connected and powered on.
[2025-04-01 23:48:26.693]: Error: Video failed to find working encoder
[2025-04-01 23:48:26.694]: Info: Adding avahi service fedora
[2025-04-01 23:48:26.695]: Info: Configuration UI available at [https://localhost:47990]
[2025-04-01 23:48:27.540]: Info: Avahi service fedora successfully established.

When starting Sunshine, if you see this, your display is misconfigured.

Moonlight connects but the screen is black

You need to start your GUI; in my case, it is gnome-session. Again, to launch this command, be sure to export DISPLAY=:99.

everything works, expect the inputs (mouse/keyboard)

This one is tricky. Be sure to have changed the necessary settings (and logged out/in to apply the group changes), then start the Xorg, Sunshine, and gnome-session commands. If it is still broken, try a reboot. If it’s still not working, I can’t say. I struggled a bit with this, and it seems related to the permissions on /dev/uinput.

/usr/lib/Xorg.wrap: Only console users are allowed to run the X server

You forgot to add the necessary line in the first config file (or your setup is using a different path for that file?).


I encountered many more issues while working on this and will try to add more details if I find anything new.

[2025-04-08 20:26:42.329]: Error: Couldn't connect to pulseaudio: Access denied
[2025-04-08 20:26:42.329]: Warning: There will be no audio
[2025-04-08 20:26:42.329]: Error: Unable to initialize audio capture. The stream will not have audio.

It was caused by doing sudo su user2

simply SSH directly into the correct user… Based on what I observed it aint an issue.


Steam Shared Library Setup

NOTE: Launch steam from your terminal if you want to see all error messages. But make sure Steam is closed while following the steps below.

I needed to set up a shared Steam library with specific permissions. It might look like there are some redundant commands, but getting this right wasn’t exactly straightforward.

Make sure Steam is fully exited before continuing.


🔧 Create the Shared Steam Library

sudo mkdir /persistent/shared-steam-library

sudo chown -R user1:steam /persistent/shared-steam-library
sudo chmod -R 775 /persistent/shared-steam-library
sudo chmod g+s /persistent/shared-steam-library

sudo setfacl -R -m u:user1:rwx /persistent/shared-steam-library
sudo setfacl -R -m u:user2:rwx /persistent/shared-steam-library

sudo setfacl -d -m u:user1:rwx /persistent/shared-steam-library
sudo setfacl -d -m u:user2:rwx /persistent/shared-steam-library

Check the permissions using:

getfacl /persistent/shared-steam-library

📁 Set Up Required Directory

Create the steamapps directory:

mkdir /persistent/shared-steam-library/steamapps/

Verify permissions again:

getfacl /persistent/shared-steam-library/steamapps

🎮 Install or Copy Your Games

At this point, you can install or copy existing games to this shared library. Don’t forget to reapply the permissions commands above if you copy any files.

Each user must also configure their own libraryfolders.vdf file. Location: ~/.local/share/Steam/steamapps

⚠️ Important: Do not share the entire Steam folder like /home/user1/.local/share/Steam. Every user should have their own home directory. Also, Proton versions (e.g., 9.0.*, experimental, hotfix) must be manually placed inside each user’s home.


🗂 Example libraryfolders.vdf

"libraryfolders"
{
	"0"
	{
		"path"		"/home/user1/.local/share/Steam"
		"label"		""
		"contentid"		"some-id"
		"totalsize"		"0"
		"update_clean_bytes_tally"		"130813730"
		"time_last_update_verified"		"1744071322"
		"apps"
		{
			"228980"		"326134489"
		}
	}
	"1"
	{
		"path"		"/persistent/shared-steam-library"
		"label"		"Shared Library"
		"contentid"		"some-id"
		"totalsize"		"1999422177280"
		"update_clean_bytes_tally"		"130813730"
		"time_last_update_verified"		"1744071322"
		"apps"
		{
		}
	}
}

✅ Final Steps

Launch Steam as user1. Head into the settings, enable compatibility for your game, and choose the Proton version you prefer (I usually go with Proton 9.0.*). You can now install or launch the game.

Everything should work smoothly at this point.

And remember, if something’s still broken, start Steam via the terminal to get detailed logs and spot any remaining permission issues.

Screenshots



Search