Files
punktfunk/docs-site/content/docs/bazzite.md
T
enricobuehler ba39b08e09
apple / swift (push) Successful in 1m6s
ci / rust (push) Successful in 5m51s
android / android (push) Successful in 6m21s
ci / web (push) Successful in 49s
ci / docs-site (push) Successful in 58s
windows-host / package (push) Successful in 8m6s
release / apple (push) Successful in 8m17s
deb / build-publish (push) Successful in 3m26s
decky / build-publish (push) Successful in 25s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 5s
ci / bench (push) Successful in 4m42s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 30s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 2m36s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 2m17s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Failing after 19s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 51s
apple / screenshots (push) Successful in 5m45s
docker / deploy-docs (push) Successful in 22s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Failing after 22s
feat(web): consolidate paired devices, self-contained sections, docs + lint
Web console
- Pairing/Library/Stats refactored into self-contained subsections that each own
  their own queries + mutations; a shared slot-based layout (view.tsx) is filled by
  the live page (containers) and Storybook (pure cards + fixtures) so the layout can't
  drift.
- All paired devices in one list on Pairing with a protocol column (punktfunk/1 +
  Moonlight), routing each unpair to the right endpoint; the redundant Clients page is
  removed.
- Library: overview grid split from the add/edit form into separate files.
- Login screen links out to the docs.

Docs
- "Console login password" section on every host page (apt/RPM/Bazzite/SteamOS/Windows)
  plus a new "Forgot your Password?" troubleshooting page, linked from the login screen.
- Console served as HTTP/1.1 over TLS (drop the unusable HTTP/3 advertising) across the
  Bun entry, launchers, systemd units, and packaging.

Tooling
- Biome now respects .gitignore (stops linting generated code), config migrated to
  2.5.1; all lint issues fixed cleanly.

Also includes this branch's in-progress host, Apple client, packaging, and CI changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 19:05:22 +02:00

5.1 KiB

title, description
title description
Bazzite — gamescope Set up a punktfunk host on Bazzite, streaming a Steam/gamescope session at your client's mode.

Bazzite already ships everything a punktfunk host needs — the NVIDIA driver, NVENC, PipeWire, and gamescope. So a Bazzite host is the most "appliance-like" setup: the host launches its own gamescope session at the client's resolution and refresh, so your games run at the mode of the device you're streaming to, not the TV the box is plugged into.

This is ideal for a dedicated game-streaming box. For a general desktop, prefer Ubuntu/Fedora KDE or GNOME.

Install

The host ships as an RPM in punktfunk's Gitea RPM registry (public), so a Bazzite / Fedora Atomic box layers and updates it with rpm-ostree. Add the repo, then layer the host plus the web console and reboot:

# Add the repo. Packages are GPG-signed (gpgcheck=1, the packages@unom.io key) AND the repo
# metadata is Gitea-signed (repo_gpgcheck=1); gpgkey lists both keys so dnf imports each.
sudo tee /etc/yum.repos.d/punktfunk.repo >/dev/null <<'REPO'
[gitea-unom-bazzite]
name=punktfunk (unom, Bazzite)
baseurl=https://git.unom.io/api/packages/unom/rpm/bazzite
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://git.unom.io/api/packages/unom/rpm/repository.key
       https://git.unom.io/api/packages/unom/generic/punktfunk-keys/1/RPM-GPG-KEY-punktfunk
REPO

# Layer the host + the web console, then reboot into the new deployment.
# (punktfunk Recommends punktfunk-web; list it explicitly so it's pulled regardless of weak-dep
# settings — the Gitea registry carries punktfunk-web, which COPR can't build.)
rpm-ostree install punktfunk punktfunk-web
systemctl reboot

rpm-ostree upgrade then tracks new builds automatically (Bazzite's auto-update timer does this for you). For a fully baked appliance image there's also a bootc Containerfile that installs the same RPMs from this registry — see packaging/bootc/ and packaging/rpm/README.md in the repo. Building from source works too (Bazzite is Fedora Atomic underneath, and its FFmpeg builds the host fine — same steps as Fedora KDE), but the registry is the supported path.

Allow controller input

Gamepad and DualSense input needs your user in the input group. On Bazzite, don't use usermod — the base is immutable and the group is managed by a recipe. Use:

ujust add-user-to-input-group

Then log out and back in. (A controller that's "detected but does nothing" is almost always this permission, not a client problem.)

Configure

The RPM ships a gamescope-ready config you can copy as your starting point:

mkdir -p ~/.config/punktfunk
cp /usr/share/punktfunk/host.env.bazzite ~/.config/punktfunk/host.env

The key settings in ~/.config/punktfunk/host.env point the host at the gamescope backend:

PUNKTFUNK_COMPOSITOR=gamescope
PUNKTFUNK_GAMESCOPE_SESSION=steam   # the host owns a Steam session at the client's mode
PUNKTFUNK_INPUT_BACKEND=gamescope
PUNKTFUNK_ZEROCOPY=1

With this, when a client connects the host starts a gamescope-session-plus (Steam) session at the client's exact resolution and refresh, and relaunches it if the client changes mode. There should be no physical gaming session already running on the box.

Run as an always-on host

Bazzite hosts are typically headless. Enable the host service and linger so it starts at boot — see Running as a Service. Because the host launches its own gamescope session per client, you don't need a separate desktop-session unit.

systemctl --user enable --now punktfunk-host
# Web console (pairing + status) — enable it and read the auto-generated login password,
# then open http://<host-ip>:3000:
systemctl --user enable --now punktfunk-web
journalctl --user -u punktfunk-web-init | sed -n 's/.*password generated: //p'

Console login password

The console is password-protected. On first start punktfunk-web-init generates a random login password and saves it to ~/.config/punktfunk/web-password (as PUNKTFUNK_UI_PASSWORD=…). Read it back at any time — from the init service's journal, or straight from the file:

journalctl --user -u punktfunk-web-init | sed -n 's/.*password generated: //p'
sed -n 's/^PUNKTFUNK_UI_PASSWORD=//p' ~/.config/punktfunk/web-password

To set your own password, edit that file (PUNKTFUNK_UI_PASSWORD=<your-password>) and restart the console: systemctl --user restart punktfunk-web. Forgot it? This is the recovery path linked from the console login screen — see Forgot your Password?.

Good to know

  • gamescope 3.16.22 or newer is required. Older versions can deadlock during capture. Bazzite's current gamescope is fine; this only bites if you've pinned an old one.
  • The mouse cursor isn't included in the captured image — a gamescope limitation for now.
  • HDR isn't supported yet on the gamescope path — gamescope's capture output is 8-bit. SDR streams normally.

Then connect a client — Moonlight works great for couch gaming, and the Apple app for Apple TV / iPad.