home-server
README.md
Sunshine
Game streaming to the Steam Deck and the MacBook. Sunshine itself is a
manually installed RPM on the host, outside Docker, because the KMS capture
it needs wasn’t worth containerising. What Portainer runs is a thin Alpine
container whose only job is manager.sh. Over SSH to the host it starts
SDDM, which logs straight into a gamescope session on the virtual
streaming display; waits for gamescope-wl to appear; starts the user
unit sunshine.service; and then polls both every thirty seconds — if
either has died, it tears the session down and starts it again. Stopping
the container stops Sunshine and SDDM in a single SSH round-trip, because
Docker’s stop grace period once ran out before the second command got its
turn.
The gamescope session is configured in
environment.d/10-gamescope-session.conf: DP-1, the DRM backend,
3024×1890 at 120 Hz, real HDR. display-mode.sh flips that between the
desk monitor and the virtual streaming display, restarting the session
cleanly instead of racing the old compositor for the DRM master.
The Steam library becomes Sunshine’s app list on its own. A .path unit
watches steamapps and runs sunshine-sync-steam.sh, which writes
apps.json — one entry per installed game, with its box art fetched and
cached — and restarts Sunshine only when the list actually changed. Each
entry launches sunshine-game.sh <appid>, which starts the game and keeps
the session alive until the game’s process has been gone for a full ninety
seconds, because shader compilation can end well before the game starts.
docker-compose.yml— the Alpine shell around the manager scriptmanager.sh— start, watch, restart, stopsystemd/—sunshine.service(started by the manager, not enabled at login), and the sync.serviceand.pathbin/—display-mode.sh,sunshine-sync-steam.sh,sunshine-game.shenvironment.d/10-gamescope-session.conf— the session’s display settings