Opens a larger view. Escape closes it.

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 script
  • manager.sh — start, watch, restart, stop
  • systemd/sunshine.service (started by the manager, not enabled at login), and the sync .service and .path
  • bin/display-mode.sh, sunshine-sync-steam.sh, sunshine-game.sh
  • environment.d/10-gamescope-session.conf — the session’s display settings