this post was submitted on 02 Jan 2026
25 points (96.3% liked)

Linux Gaming

23550 readers
373 users here now

Discussions and news about gaming on the GNU/Linux family of operating systems (including the Steam Deck). Potentially a $HOME away from home for disgruntled /r/linux_gaming denizens of the redditarian demesne.

This page can be subscribed to via RSS.

Original /r/linux_gaming pengwing by uoou.

No memes/shitposts/low-effort posts, please.

Resources

WWW:

Discord:

IRC:

Matrix:

Telegram:

founded 2 years ago
MODERATORS
 

I am trying to set up sunshine to capture using the wlr method and do it headlessly. no dummy plug, no monitor. Supposedly this is possible, but I'm having trouble.

first I create the user in fedora and give them the permissions needed. I set up setd and create the service file for systemd to fire a sway instance. I edit sway config for that user to include the virtual display output by including this line:

output HEADLESS-1 { pos 0,0 mode 3840x2160@60hz }

That should make a virtual monitor that wayland can render to and sunshine can capture the framebuffer from sway with.

Sway launches fine, sunshine see the wayland instance, but it sees no monitor attached so it has nothing in it can capture from.

I cannot use swaymsg from SSH since its not part of that wayland session so it cant access it and pass commands to it. it just complains about socket errors. So I dont know what I'm supposed to do to make this headlessly run.

top 5 comments
sorted by: hot top controversial new old
[–] themoken@startrek.website 10 points 3 weeks ago* (last edited 3 weeks ago) (2 children)

I have this setup with Plasma, and it is probably easier to do this at the Linux level. I added this to my kernel command line: drm.edid_firmware=DP-1:edid/lg-ultra.bin video=DP-1:3840x2160@60e

Where that EDID file I dumped from a spare monitor using a method I got here.

Anyway, it can be tricky to pick the right device, but I can confirm Sunshine sees it and works properly, and it can be managed like a normal monitor.

[–] vividspecter@aussie.zone 3 points 3 weeks ago

This approach is probably the most reliable and works with any AMD card at the least.

[–] muusemuuse@sh.itjust.works 2 points 3 weeks ago* (last edited 3 weeks ago)

I think I actually figured it out without the EDID injection, I forgot a line in the sway config. I'll test it after work today and report back what I have if it works as this method is a cleaner way of getting headless zero copy.

EDIT: okay, posted. feel free to suggest corrections as I'm still learning.

[–] muusemuuse@sh.itjust.works 1 points 3 weeks ago* (last edited 1 week ago) (1 children)

Okay here's what I stumbled through.

This is on a fedora server machine with an intel ARC B580. I intentionally chose fedora because my fedora skills are ass and I wanted to improve them so.....

  1. enable rpmfusion repos - go here (https://docs.fedoraproject.org/en-US/quick-docs/rpmfusion-setup/) make sure to include nonfree. we need the intel-media-driver from there. The one included in the fedora repos is incomplete and generally wont be enough for what we want.
  2. enable the copr repo for sunshine - at this time, there isnt anything in stable for fedora 43, so we enable the beta repo with "sudo dnf copr enable lizardbyte/beta"
  3. install the packages - run "sudo dnf install intel-media-driver sway seatd nano pipewire wireplumber Sunshine"
  4. open ports on the fedora firewall - I'm a hack and used cockpit for this. log into the cockpit UI and got to Networking->edit rules and zones->add services. add TCP 47990, 47984, 47989, 48010 and UDP 47998-48000
  5. add a sunshine user on the machine - run "sudo adduser sunshine -m"
  6. set a password for the sunshine user - run "sudo passwd sunshine"
  7. add sunshine user to the required groups - run "sudo usermod -aG video,render,seat,input sunshine"
  8. enable seatd at boot so the sunshine user can create a headless wayland session in the background without having to be logged in - run "sudo systemctl enable --now seatd"
  9. enable linger so things can run by themselves as that user - run "sudo loginctl enable-linger sunshine"
  10. There is an issue with sunshine rules in fedora not matching because the PS5 controller name attribute isn't where it is in other distros. So we tell it to look a little deeper. Create a helper script to evaluate and throw controllers into the input group - run "sudo nano /usr/local/bin/sunshines-little-helper.sh" and ensure the following is included in the file:
#!/bin/bash
# Called by udev when a hidraw device appears.
# $1 = sysfs path of the device (from %p)

DEV_SYSFS=$(readlink -f "/sys/$1")

# Exit if no device passed
if [ -z "$DEV_SYSFS" ] || [ ! -e "$DEV_SYSFS" ]; then
    echo "sunshine-helper: invalid device path: $DEV_SYSFS" >&2
    exit 1
fi

# Loop through input child devices to detect Sunshine virtual controller
SUNSHINE_FOUND=0
for input_dir in "$DEV_SYSFS"/device/input/input*; do
    [ -d "$input_dir" ] || continue
    NAME=$(cat "$input_dir/name" 2>/dev/null)
    case "$NAME" in
        "Sunshine PS5 (virtual) pad"*|"Sunshine X-Box One (virtual) pad"*|"Sunshine Nintendo (virtual) pad"*|"Sunshine gamepad (virtual) motion sensors"*)
            SUNSHINE_FOUND=1
            break
            ;;
    esac
done

# If not a Sunshine virtual device, do nothing
[ "$SUNSHINE_FOUND" -eq 1 ] || exit 0

# Resolve the /dev/hidrawX node corresponding to the sysfs path
DEV_NODE=$(udevadm info -q path -p "$DEV_SYSFS" | xargs -I{} basename {} | sed 's/^/\/dev\//')

# Apply group/permissions
chgrp input "$DEV_NODE"
chmod 0660 "$DEV_NODE"
  1. make this script executable - run "sudo chmod +x /usr/local/bin/sunshines-little-helper.sh"
  2. tell udev to run our script if it suspects a sunshine controller might have been connected - run "sudo nano /etc/udev/rules.d/99-sunshine.rules" ensure the following is included in the file:
# Fedora doesnt present the PS5 controllers with the name attribute where normal sunshine rules
# expect it, so we have to call an external script the run additional checks and act accordingly
# This method is gross.  If anyone has a better idea, please post it somewhere and euthanize this

KERNEL=="hidraw*", KERNELS=="*054C:0CE6*", RUN+="/usr/local/bin/sunshines-little-helper.sh %p"
  1. create config directories - log in as the sunshine user we created. run "mkdir -p ~/.config/sway ~/.config/sunshine ~/.config/systemd/user"
  2. create sway config - run "nano ~/.config/sway/config" and ensure the following is included in the file:
output HEADLESS-1 {
pos 0,0
mode 3840x2160@60hz
render_bit_depth 10
}
exec swaymsg create_output HEADLESS-1

default_border none
default_floating_border none
  1. create the initial sunshine config - run "nano ~/.config/sunshine/sunshine.conf" and ensure the following is included in the file:
capture = wlr
encoder = vaapi
  1. config systemd to launch sway at boot - run "nano ~/.config/systemd/user/sway.service" and make the file look like this:
[Unit]
Description=Sway Wayland compositor
Documentation=man:sway(5)
After=pipewire.socket wireplumber.service
Wants=pipewire.socket wireplumber.service

[Service]
ExecStart=/usr/bin/sway
Restart=on-failure
RestartSec=2
Environment=WLR_RENDERER=vulkan
Environment=XDG_SESSION_TYPE=wayland
Environment=LIBSEAT_BACKEND=seatd
Environment=XDG_CURRENT_DESKTOP=sway

[Install]
WantedBy=default.target
  1. config systemd to launch sunshine at boot (the way we want it to) - run "EDITOR=nano systemctl --user edit sunshine" and put the following in the area that will apply the override:
[Unit]
After=sway.service
Requires=sway.service

[Service]
Environment=WAYLAND_DISPLAY=wayland-1
Environment=XDG_SESSION_TYPE=wayland

[Install]
WantedBy=default.target
  1. enable the systemd services - run "systemctl --user daemon-reload" then run "systemctl --user enable --now sway" and "systemctl --user enable --now sunshine"
  2. configure sway to change resolution to whatever the moonlight client asks for - access the sunshine webUI by pointing a web browser to https://(your server IP):47990/ and go to the configuration tab and add the following DO command
sh -c "swaymsg output HEADLESS-1 pos 0 0 res \"${SUNSHINE_CLIENT_WIDTH}x${SUNSHINE_CLIENT_HEIGHT}@${SUNSHINE_CLIENT_FPS}Hz\""

and if you want an undo command set it to

sh -c "swaymsg output HEADLESS-1 pos 0 0 res \"${SUNSHINE_CLIENT_WIDTH}x${SUNSHINE_CLIENT_HEIGHT}@${SUNSHINE_CLIENT_FPS}Hz\""

There, you now have a headless, resolution-matching, zero-copy, lightweight sunshine install and you didn't need any dummy plugs, connected monitors, EDID injection, etc.

There are likely things I missed but this is what I've got so far.

[–] muusemuuse@sh.itjust.works 1 points 3 weeks ago

Also, if you are using an intel ARC GPU, you might want to run through fwupd as there are issues with these cards that the windows installer resolves during driver install that we cant run on linux that way, so we can tell linux to do that step for us with fwupd.