docs: restructure host setup by distro, configuration by compositor
apple / swift (push) Successful in 1m8s
apple / screenshots (push) Successful in 5m33s
android / android (push) Successful in 4m43s
arch / build-publish (push) Successful in 5m38s
ci / web (push) Successful in 1m3s
ci / docs-site (push) Successful in 1m17s
ci / rust (push) Successful in 4m48s
ci / bench (push) Successful in 5m7s
decky / build-publish (push) Successful in 14s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 5s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 5s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 3s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 4s
deb / build-publish (push) Successful in 4m29s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m16s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 10m24s
docker / deploy-docs (push) Successful in 6s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 10m3s
apple / swift (push) Successful in 1m8s
apple / screenshots (push) Successful in 5m33s
android / android (push) Successful in 4m43s
arch / build-publish (push) Successful in 5m38s
ci / web (push) Successful in 1m3s
ci / docs-site (push) Successful in 1m17s
ci / rust (push) Successful in 4m48s
ci / bench (push) Successful in 5m7s
decky / build-publish (push) Successful in 14s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 5s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 5s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 3s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 4s
deb / build-publish (push) Successful in 4m29s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m16s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 10m24s
docker / deploy-docs (push) Successful in 6s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 10m3s
Split the docs' single distro×desktop axis (ubuntu-gnome / ubuntu-kde / fedora-kde) into two,
which deduplicates the shared mechanics and scales to distros that run several desktops (Arch):
- Install the host — per distro/OS (ubuntu, fedora, arch, bazzite, steamos-host, windows-host):
GPU driver + package + input group, then a canonical "Configure your desktop" funnel.
- Configure your desktop — per compositor (kde, gnome, gamescope, sway): host.env, compositor
quirks, the headless session, and starting the host.
New shared web-console page (enable · login password · arm pairing) removes the console/password
block that was copy-pasted across all seven host pages. Merged ubuntu-gnome + ubuntu-kde into
ubuntu; renamed fedora-kde to fedora; kept bazzite and steamos-host as dedicated appliance guides
(trimmed of duplication). Moved the KWin headless session, the GNOME EGL/lock traps, and the
gamescope attach/managed model out of the distro pages onto their compositor pages.
Fixed while restructuring: distro-specific paths on kde (kde-desktop-setup.sh is Fedora/Bazzite-only;
the .deb ships host.env.kde under /usr/share/punktfunk-host), the interactive "start the host" step
that was lost in the merge, sway over-claiming Hyprland, and a pre-existing broken anchor in
how-it-works.
Removal of the three old pages was captured by the preceding commit 8ebb614 (a concurrent commit
swept up the staged git-rm); the net docs tree is correct. Fumadocs build + internal link/anchor
check green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -58,25 +58,30 @@ tuning, and example configs. Updates later are just `sudo pacman -Syu`.
|
||||
|
||||
## 4. Configure and run
|
||||
|
||||
The host runs as a systemd **`--user`** service — it needs your session's PipeWire and D-Bus.
|
||||
Copy a starting config, enable the service, and enable linger so it starts at boot without a login:
|
||||
The host runs as a systemd **`--user`** service — it needs your session's PipeWire and D-Bus. Copy a
|
||||
starting config:
|
||||
|
||||
```sh
|
||||
mkdir -p ~/.config/punktfunk
|
||||
cp /usr/share/punktfunk/host.env.example ~/.config/punktfunk/host.env # then edit
|
||||
cp /usr/share/punktfunk/host.env.example ~/.config/punktfunk/host.env
|
||||
```
|
||||
|
||||
How the host creates its virtual display and injects input depends on your desktop, not your distro —
|
||||
edit `host.env` for the desktop you run, following its page for the exact settings and any quirks:
|
||||
|
||||
- [KDE Plasma (KWin)](/docs/kde)
|
||||
- [GNOME (Mutter)](/docs/gnome)
|
||||
- [Steam / gamescope](/docs/gamescope)
|
||||
- [Sway / wlroots](/docs/sway)
|
||||
|
||||
Then enable the service and turn on linger so it starts at boot without a login:
|
||||
|
||||
```sh
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now punktfunk-host
|
||||
sudo loginctl enable-linger "$USER"
|
||||
```
|
||||
|
||||
Which compositor the host captures depends on your desktop — it drives a per-client virtual output
|
||||
via KWin (Plasma), Mutter (GNOME), or wlroots (Sway), or spawns a headless **gamescope** session
|
||||
per connect. For a headless appliance, the package also ships `punktfunk-kde-session.service`
|
||||
(a dedicated `kwin --virtual` session, same as the [Fedora KDE](/docs/fedora-kde#3-kwin-streaming-session)
|
||||
guide — `cp /usr/share/punktfunk/host.env.kde ~/.config/punktfunk/host.env` and enable it alongside
|
||||
the host). See [Configuration](/docs/configuration) for every knob and
|
||||
[Running as a Service](/docs/running-as-a-service) for the service model.
|
||||
|
||||
Check it came up:
|
||||
|
||||
```sh
|
||||
@@ -84,27 +89,10 @@ systemctl --user status punktfunk-host # active
|
||||
journalctl --user -u punktfunk-host -f # watch a client connect
|
||||
```
|
||||
|
||||
### Web console
|
||||
|
||||
The console (status, paired devices, arm pairing) ships as `punktfunk-web` — enable it, then open
|
||||
`http://<host-ip>:47992`:
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-web
|
||||
```
|
||||
|
||||
#### Console login password
|
||||
|
||||
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:
|
||||
|
||||
```sh
|
||||
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, edit that file and `systemctl --user restart punktfunk-web`. Forgot it? See
|
||||
[Forgot your Password?](/docs/forgot-password).
|
||||
Enable the browser console, find your login password, and arm PIN pairing from
|
||||
[The Web Console](/docs/web-console). For a headless KWin appliance that streams at boot with no
|
||||
graphical login, see [KDE → Headless session](/docs/kde#headless-session). Full reference:
|
||||
[Configuration](/docs/configuration) · [Running as a Service](/docs/running-as-a-service).
|
||||
|
||||
## 5. Open the firewall (if you have one)
|
||||
|
||||
@@ -147,9 +135,9 @@ opened. Full port lists (`nftables`, explicit ports) are in
|
||||
## 6. Connect a client
|
||||
|
||||
From any [client](/docs/clients), `--discover` finds the host on the LAN. On first connect, complete
|
||||
the **PIN pairing** — arm it from the host's web console, which displays a 4-digit PIN to type into
|
||||
the client. (Pairing is required by default; pass `serve --open` only if you deliberately want to
|
||||
disable it.) See [Clients](/docs/clients) and [Pairing](/docs/pairing).
|
||||
the **PIN pairing**: arm it from [The Web Console](/docs/web-console#arm-pairing), which displays a
|
||||
4-digit PIN to type into the client. (Pairing is required by default; pass `serve --open` only if
|
||||
you deliberately want to disable it.) See [Clients](/docs/clients) for per-platform setup.
|
||||
|
||||
## Appendix — build from source (PKGBUILD)
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ mid-stream. You flip between Gaming Mode and Desktop with Bazzite's normal Steam
|
||||
`host.env` forces a mode.
|
||||
|
||||
> Ideal for a dedicated game-streaming box that you also occasionally want as a remote desktop. For a
|
||||
> pure desktop machine, [Ubuntu/Fedora KDE](/docs/ubuntu-kde) or [GNOME](/docs/ubuntu-gnome) are
|
||||
> simpler.
|
||||
> pure desktop machine, install on [Ubuntu](/docs/ubuntu) or [Fedora](/docs/fedora) and configure the
|
||||
> [KDE](/docs/kde) or [GNOME](/docs/gnome) desktop directly — simpler.
|
||||
|
||||
> New here? Read [Security & Safe Use](/docs/security) first — a streaming host is remote control of
|
||||
> the machine, so keep it on a trusted LAN or VPN and require pairing.
|
||||
@@ -60,7 +60,7 @@ For a fully baked appliance image there's also a **bootc** Containerfile that in
|
||||
from the registry at image-build time — see `packaging/bootc/` in the repo. Plain `rpm-ostree`
|
||||
layering from the [RPM registry](https://git.unom.io/unom/-/packages) keeps working too (see
|
||||
`packaging/bazzite/README.md`), but the sysext is the supported default. Building from source
|
||||
also works (Bazzite is Fedora Atomic underneath — same steps as [Fedora KDE](/docs/fedora-kde)).
|
||||
also works (Bazzite is Fedora Atomic underneath — same steps as [Fedora](/docs/fedora)).
|
||||
|
||||
## Allow controller input
|
||||
|
||||
@@ -99,15 +99,14 @@ PUNKTFUNK_GAMESCOPE_ATTACH=1 # Gaming Mode = attach to the box's own session
|
||||
|
||||
For Gaming Mode there are two models (pick one; the shipped default is **attach**):
|
||||
|
||||
- **Attach** (`PUNKTFUNK_GAMESCOPE_ATTACH=1`, the default) — the **box** owns its gamescope session
|
||||
and decides Gaming vs Desktop via the normal Steam UI. The host just attaches to whatever's live
|
||||
and never tears it down, so switching Desktop ↔ Game is rock-solid and disconnecting leaves the box
|
||||
where it was. The streamed game-mode resolution is the box's gamescope mode
|
||||
(`SCREEN_WIDTH/HEIGHT` in `/etc/gamescope-session-plus/sessions.d/steam`), not the client's.
|
||||
- **Managed** (`PUNKTFUNK_GAMESCOPE_MANAGED=1`, and remove the attach line) — the host tears the
|
||||
box's gamescope down on connect and launches its **own** at the *client's* exact resolution and
|
||||
refresh, restoring on idle. Client-mode-following, but it can't coexist with a box-owned game-mode
|
||||
session, and there must be **no physical gaming session already running**.
|
||||
- **Attach** (`PUNKTFUNK_GAMESCOPE_ATTACH=1`, the default) — the **box** owns its gamescope session,
|
||||
the host attaches to whatever's live and never tears it down, and the streamed game-mode resolution
|
||||
is the box's own gamescope mode. Switching Desktop ↔ Game is rock-solid.
|
||||
- **Managed** (`PUNKTFUNK_GAMESCOPE_MANAGED=1`, and remove the attach line) — the host launches its
|
||||
**own** gamescope at the *client's* exact resolution and refresh. Client-mode-following, but there
|
||||
must be no physical gaming session already running.
|
||||
|
||||
Full treatment: [Steam / gamescope → Attach vs managed](/docs/gamescope#attach-vs-managed).
|
||||
|
||||
Mid-stream Gaming ↔ Desktop following (`PUNKTFUNK_SESSION_WATCH`) is **on by default** on
|
||||
Bazzite/SteamOS. See [Configuration](/docs/configuration) for the full list of knobs.
|
||||
@@ -116,8 +115,8 @@ Bazzite/SteamOS. See [Configuration](/docs/configuration) for the full list of k
|
||||
|
||||
The **virtual output** (video) for the Desktop session needs no config — the host package ships an
|
||||
`io.unom.Punktfunk.Host.desktop` file whose `X-KDE-Wayland-Interfaces` grants the host KWin's
|
||||
restricted screencast protocol on a normal interactive Plasma session (least-privilege, the same
|
||||
mechanism krfb/krdp use). After a **fresh host install, log out and back into the Desktop session
|
||||
restricted screencast protocol on a normal interactive Plasma session (background:
|
||||
[KDE Plasma](/docs/kde)). After a **fresh host install, log out and back into the Desktop session
|
||||
once** so KWin re-reads that grant.
|
||||
|
||||
The one thing a normal KDE login lacks is the RemoteDesktop grant for headless **input** injection.
|
||||
@@ -138,26 +137,11 @@ Desktop; it follows whichever the box is in.
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-host
|
||||
# Web console (pairing + status) — enable it and read the auto-generated login password,
|
||||
# then open http://<host-ip>:47992:
|
||||
systemctl --user enable --now punktfunk-web
|
||||
journalctl --user -u punktfunk-web-init | sed -n 's/.*password generated: //p'
|
||||
systemctl --user enable --now punktfunk-web # web console: pairing + status
|
||||
```
|
||||
|
||||
### 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:
|
||||
|
||||
```sh
|
||||
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?](/docs/forgot-password).
|
||||
Then open [The Web Console](/docs/web-console) for the login password and to
|
||||
[arm pairing](/docs/web-console#arm-pairing).
|
||||
|
||||
## Good to know
|
||||
|
||||
@@ -170,5 +154,7 @@ These apply to the **Gaming Mode (gamescope)** path; the KDE Desktop path is una
|
||||
- **HDR isn't supported yet** on the gamescope path — gamescope's capture output is 8-bit. SDR streams
|
||||
normally.
|
||||
|
||||
Canonical list: [gamescope → Known limits](/docs/gamescope#known-limits).
|
||||
|
||||
Then [connect a client](/docs/clients) — Moonlight works great for couch gaming, and the Apple app for
|
||||
Apple TV / iPad.
|
||||
|
||||
@@ -48,8 +48,8 @@ let you pick a mode or default to the device's display.)
|
||||
|
||||
## gamescope / session following (Linux, Bazzite/SteamOS)
|
||||
|
||||
Two mutually-exclusive models for a Steam/gamescope box. See [Bazzite](/docs/bazzite) for the full
|
||||
picture.
|
||||
Two mutually-exclusive models for a Steam/gamescope box. See [Steam / gamescope](/docs/gamescope) for
|
||||
the full picture (and [Bazzite](/docs/bazzite) for that distro's specifics).
|
||||
|
||||
| Setting | Values | Meaning |
|
||||
|---|---|---|
|
||||
@@ -62,6 +62,8 @@ picture.
|
||||
|
||||
## Compositor-specific (Linux)
|
||||
|
||||
See your desktop page ([KDE](/docs/kde), [GNOME](/docs/gnome)) for when to set these.
|
||||
|
||||
> **Managing virtual displays** — keep-alive after disconnect, exclusive vs. extend, and (on
|
||||
> Windows/KDE) persistent per-client scaling — now has its own settings surface in the web console
|
||||
> and `display-settings.json`. See [Virtual displays](/docs/virtual-displays). The two
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
---
|
||||
title: Fedora
|
||||
description: Install the punktfunk host on Fedora from the RPM registry.
|
||||
---
|
||||
|
||||
Install a punktfunk host on **Fedora** from the self-hosted RPM registry. The host installs as an
|
||||
RPM-managed systemd **`--user`** service and updates with `dnf upgrade` like the rest of your
|
||||
system — no building required. It works with either **KDE Plasma** or **GNOME**; the
|
||||
desktop-specific setup (which compositor captures, headless sessions, quirks) lives on the
|
||||
[desktop configure pages](#3-configure-your-desktop). Host encode is **NVENC on NVIDIA** and **VAAPI on
|
||||
AMD/Intel** (`PUNKTFUNK_ENCODER=auto` picks per GPU).
|
||||
|
||||
> New here? Read [Security & Safe Use](/docs/security) first — a streaming host is remote control of
|
||||
> the machine, so keep it on a trusted LAN or VPN and require pairing.
|
||||
|
||||
Install is two parts: **GPU driver** → **host RPM**. Then point the host at your desktop from the
|
||||
[desktop configure pages](#3-configure-your-desktop).
|
||||
|
||||
## 1. NVIDIA driver (RPM Fusion akmod)
|
||||
|
||||
Enable RPM Fusion (free + nonfree), then install the akmod driver + CUDA. RPM Fusion's nonfree
|
||||
NVIDIA repo is sometimes pre-enabled on some spins; the full free/nonfree repos below are still
|
||||
needed (they carry the NVENC ffmpeg in the next step).
|
||||
|
||||
```sh
|
||||
sudo dnf install \
|
||||
https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm \
|
||||
https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
|
||||
sudo dnf install akmod-nvidia xorg-x11-drv-nvidia-cuda
|
||||
```
|
||||
|
||||
**NVENC ffmpeg.** Fedora ships `ffmpeg-free`, which is built **without** NVENC — the host can't
|
||||
encode with it. Swap to RPM Fusion's ffmpeg:
|
||||
|
||||
```sh
|
||||
sudo dnf install --allowerasing ffmpeg ffmpeg-libs
|
||||
ffmpeg -hide_banner -encoders | grep nvenc # expect hevc_nvenc / av1_nvenc / h264_nvenc
|
||||
```
|
||||
|
||||
**Secure Boot.** If `mokutil --sb-state` says *enabled*, the akmod module is signed with a
|
||||
locally-generated key that must be enrolled once:
|
||||
|
||||
```sh
|
||||
sudo akmods --force # build + sign the module
|
||||
sudo mokutil --import /etc/pki/akmods/certs/public_key.der # set a one-time password
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
On the next boot a blue **MOK Manager** screen appears **on the machine's console** (not over
|
||||
SSH): *Enroll MOK → Continue → Yes → (the password) → Reboot*. Then verify:
|
||||
|
||||
```sh
|
||||
nvidia-smi # driver loads
|
||||
ffmpeg -hide_banner -encoders | grep nvenc
|
||||
```
|
||||
|
||||
(Or disable Secure Boot in firmware to skip the MOK step — fine for a dedicated test box.)
|
||||
|
||||
**AMD / Intel (VAAPI).** No akmod needed — the Mesa stack provides the VAAPI encoder. Install the
|
||||
freeworld VAAPI drivers for full codec support (`mesa-va-drivers-freeworld` for AMD from RPM Fusion,
|
||||
`intel-media-driver` for Intel); on a desktop these are usually already present. The host auto-picks
|
||||
VAAPI on these GPUs.
|
||||
|
||||
## 2. Install the host (RPM)
|
||||
|
||||
The host is published to the self-hosted Gitea RPM registry, in a per-Fedora-release group (an RPM
|
||||
is soname-coupled to its base, so Fedora 44 has its own `fedora-44` group). Add the repo and
|
||||
install:
|
||||
|
||||
```sh
|
||||
sudo tee /etc/yum.repos.d/punktfunk.repo >/dev/null <<'REPO'
|
||||
[punktfunk]
|
||||
name=punktfunk
|
||||
baseurl=https://git.unom.io/api/packages/unom/rpm/fedora-44
|
||||
enabled=1
|
||||
# Packages are GPG-signed (gpgcheck=1) AND the repo metadata is Gitea-signed (repo_gpgcheck=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
|
||||
|
||||
sudo dnf install punktfunk
|
||||
sudo usermod -aG input "$USER" # /dev/uinput access for virtual gamepads (re-login to apply)
|
||||
```
|
||||
|
||||
Updates later are just `sudo dnf upgrade punktfunk`. The package ships the systemd user units, the
|
||||
udev rule, the UDP socket-buffer sysctl tuning, and example configs.
|
||||
|
||||
> No matching `fedora-NN` group for your release yet? Build one with the same toolchain CI uses —
|
||||
> `docker build --build-arg FEDORA_VERSION=NN -f ci/fedora-rpm.Dockerfile -t pf-rpm ci` then run
|
||||
> `packaging/rpm/build-rpm.sh` inside it — or build from source (appendix below).
|
||||
|
||||
## 3. Configure your desktop
|
||||
|
||||
How the host creates its virtual display and injects input depends on your desktop, not your distro.
|
||||
Continue on the page for the desktop you run — it covers your `host.env`, any compositor quirks, and
|
||||
starting the host:
|
||||
|
||||
- [KDE Plasma (KWin)](/docs/kde)
|
||||
- [GNOME (Mutter)](/docs/gnome)
|
||||
- [Steam / gamescope](/docs/gamescope)
|
||||
- [Sway / wlroots](/docs/sway)
|
||||
|
||||
Enable the browser management console (status, paired devices, arm pairing) — see
|
||||
[Web Console](/docs/web-console).
|
||||
|
||||
For a headless KWin appliance that streams at boot with no graphical login, see
|
||||
[KDE → Headless session](/docs/kde#headless-session).
|
||||
|
||||
Full config reference: [Configuration](/docs/configuration). Service model:
|
||||
[Running as a Service](/docs/running-as-a-service).
|
||||
|
||||
## 4. Connect a client
|
||||
|
||||
From any [client](/docs/clients), `--discover` finds the host on the LAN. On first connect, complete
|
||||
the **PIN pairing** — arm it from the host's [web console](/docs/web-console#arm-pairing), which
|
||||
displays a 4-digit PIN to type into the client. See [Clients](/docs/clients) and
|
||||
[Pairing](/docs/pairing).
|
||||
|
||||
## Appendix — build from source
|
||||
|
||||
If there's no RPM for your Fedora release and you don't want to build one, compile the host directly
|
||||
(no clean updates / no packaged units — you wire those up by hand):
|
||||
|
||||
```sh
|
||||
sudo dnf install gcc gcc-c++ make cmake clang clang-devel nasm git \
|
||||
pipewire-devel wayland-devel wayland-protocols-devel libxkbcommon-devel opus-devel \
|
||||
libdrm-devel mesa-libgbm-devel mesa-libEGL-devel mesa-libGLES-devel libva-devel \
|
||||
ffmpeg-devel libei-devel
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
git clone https://git.unom.io/unom/punktfunk.git && cd punktfunk
|
||||
cargo build --release -p punktfunk-host
|
||||
```
|
||||
|
||||
Then write `~/.config/punktfunk/host.env` (as in `/usr/share/punktfunk/host.env.kde`, but the host
|
||||
binary is `target/release/punktfunk-host`) and run it inside your desktop session — for a headless
|
||||
KWin appliance see [KDE → Headless session](/docs/kde#headless-session).
|
||||
@@ -8,21 +8,20 @@ password. That password is generated — or, on Windows, chosen — when the con
|
||||
it lives on the **host**. So if you can't get past the login screen, you recover or change it on the
|
||||
host machine itself, not from the browser.
|
||||
|
||||
New to the console? See [The Web Console](/docs/web-console) to enable it and arm pairing.
|
||||
|
||||
> This is **only** the web console login. It is **not** your client/device pairing — if a client
|
||||
> won't connect, that's [Pairing](/docs/pairing), not this password.
|
||||
|
||||
## Find your host
|
||||
|
||||
Jump to your host platform for exactly where the password lives and how to read or reset it:
|
||||
Find your host platform for exactly where the password lives, then read or reset it below:
|
||||
|
||||
| Host | Where the password lives | Section |
|
||||
|------|--------------------------|---------|
|
||||
| **Ubuntu — GNOME** | `~/.config/punktfunk/web-password` | [Console login password](/docs/ubuntu-gnome#console-login-password) |
|
||||
| **Ubuntu — KDE Plasma** | `~/.config/punktfunk/web-password` | [Console login password](/docs/ubuntu-kde#console-login-password) |
|
||||
| **Fedora — KDE Plasma** | `~/.config/punktfunk/web-password` | [Console login password](/docs/fedora-kde#console-login-password) |
|
||||
| **Bazzite — gamescope** | `~/.config/punktfunk/web-password` | [Console login password](/docs/bazzite#console-login-password) |
|
||||
| **SteamOS (host)** | `~/.config/punktfunk/web.env` | [Console login password](/docs/steamos-host#console-login-password) |
|
||||
| **Windows host** | `%ProgramData%\punktfunk\web-password` | [Console login password](/docs/windows-host#console-login-password) |
|
||||
| **Linux packages (apt / RPM / Bazzite)** | `~/.config/punktfunk/web-password` | [Login password](/docs/web-console#login-password) |
|
||||
| **SteamOS (host)** | `~/.config/punktfunk/web.env` | [Login password](/docs/web-console#login-password) |
|
||||
| **Windows host** | `%ProgramData%\punktfunk\web-password` | [Login password](/docs/web-console#login-password) · [Windows Host](/docs/windows-host) |
|
||||
|
||||
## The short version
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
title: Steam / gamescope
|
||||
description: Configure a gamescope/Steam host — attach vs managed, session following, and limits.
|
||||
---
|
||||
|
||||
gamescope is the compositor behind Steam **Gaming Mode** — the couch/handheld game UI on Bazzite,
|
||||
SteamOS, or any distro running a gamescope session. The host **auto-detects** gamescope from your
|
||||
live session, so you rarely need to set anything here. It also **follows a Gaming ↔ Desktop switch
|
||||
mid-stream** — flip between Gaming Mode and the desktop with Steam's normal UI and the host
|
||||
re-targets whatever's running without a reconnect.
|
||||
|
||||
This page covers the gamescope-specific choices. To get a host running on an appliance box, start
|
||||
from the install guide for your OS: [Bazzite](/docs/bazzite) or [SteamOS (Host)](/docs/steamos-host).
|
||||
|
||||
> New here? Read [Security & Safe Use](/docs/security) first — a streaming host is remote control of
|
||||
> the machine, so keep it on a trusted LAN or VPN and require pairing.
|
||||
|
||||
## Attach vs managed
|
||||
|
||||
There are two mutually-exclusive models for a gamescope box; pick one. The shipped default is
|
||||
**attach**.
|
||||
|
||||
- **Attach** (`PUNKTFUNK_GAMESCOPE_ATTACH=1`, the default) — the **box** owns its gamescope session
|
||||
and decides Gaming vs Desktop via the normal Steam UI. The host just attaches to whatever's live
|
||||
and never tears it down, so switching Desktop ↔ Game is rock-solid and disconnecting leaves the box
|
||||
where it was. The streamed game-mode resolution is the box's gamescope mode
|
||||
(`SCREEN_WIDTH/HEIGHT` in `/etc/gamescope-session-plus/sessions.d/steam`), not the client's.
|
||||
- **Managed** (`PUNKTFUNK_GAMESCOPE_MANAGED=1`, and remove the attach line) — the host tears the
|
||||
box's gamescope down on connect and launches its **own** at the *client's* exact resolution and
|
||||
refresh, restoring on idle. Client-mode-following, but it can't coexist with a box-owned game-mode
|
||||
session, and there must be **no physical gaming session already running**.
|
||||
|
||||
## Session following
|
||||
|
||||
`PUNKTFUNK_SESSION_WATCH` follows a Gaming ↔ Desktop switch **mid-stream** — the host rebuilds the
|
||||
backend in place, with no reconnect. It is **on by default** on Bazzite/SteamOS; set `0` to disable.
|
||||
One host service covers both faces of the box: it streams Gaming Mode over gamescope and the desktop
|
||||
over its own compositor, and re-targets whichever is live on each switch.
|
||||
|
||||
## Start the host
|
||||
|
||||
On an appliance box (Bazzite, SteamOS) the install guide already enables the host service for you. On
|
||||
any other distro running a gamescope session, start it from your session — the default attach model
|
||||
just latches onto whatever gamescope session is live:
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-host
|
||||
```
|
||||
|
||||
Then bring up [The Web Console](/docs/web-console) to arm pairing.
|
||||
|
||||
## gamescope knobs
|
||||
|
||||
The gamescope-specific settings in `host.env`. Leave them unset to auto-detect; set one only to force
|
||||
a model. See the full [Configuration reference](/docs/configuration) for every other knob.
|
||||
|
||||
| Setting | Values | Meaning |
|
||||
|---|---|---|
|
||||
| `PUNKTFUNK_GAMESCOPE_ATTACH` | `1` | **Attach** model: the box owns its gamescope session; the host captures whatever's live and never tears it down. Streamed resolution is the box's gamescope mode. The default. |
|
||||
| `PUNKTFUNK_GAMESCOPE_MANAGED` | `1` | **Managed** model: the host tears the box's gamescope down on connect and launches its own at the client's exact mode, restoring on idle. Doesn't coexist with a box-owned game-mode session. |
|
||||
| `PUNKTFUNK_GAMESCOPE_SESSION` | `steam` | The host owns a `gamescope-session-plus` (Steam) session at the client's mode — a headless appliance with no physical session running. |
|
||||
| `PUNKTFUNK_GAMESCOPE_NODE` | `auto` · node id | Discover and capture a **running** gamescope's PipeWire node at a fixed mode. Do **not** combine with `SESSION`. |
|
||||
| `PUNKTFUNK_GAMESCOPE_APP` | command | For an ad-hoc bare-gamescope session, the nested command to run (e.g. `vkcube`). |
|
||||
| `PUNKTFUNK_SESSION_WATCH` | `1` · `0` | Follow a Gaming ↔ Desktop switch mid-stream (rebuild in place, no reconnect). On by default on Bazzite/SteamOS; set `0` to disable. |
|
||||
|
||||
## Known limits
|
||||
|
||||
These apply to the **Gaming Mode (gamescope)** path only; the desktop path is unaffected.
|
||||
|
||||
- **gamescope 3.16.22 or newer is required.** Older versions can deadlock during capture. Bazzite's
|
||||
and SteamOS'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 on the gamescope path** — gamescope's capture output is 8-bit. SDR streams
|
||||
normally.
|
||||
|
||||
To stream the KDE Plasma desktop of a Steam box instead, see [KDE Plasma](/docs/kde). To bring up the
|
||||
web console and pair a client, see [The Web Console](/docs/web-console).
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
title: GNOME (Mutter)
|
||||
description: Configure a punktfunk host for GNOME — host.env, the EGL/lock traps, and a headless session.
|
||||
---
|
||||
|
||||
Configure a host running **GNOME**. The host drives GNOME's Mutter compositor to create a per-client
|
||||
virtual display over D-Bus (`RecordVirtual`), zero-copy. This page assumes the host is already
|
||||
installed — see [Ubuntu](/docs/ubuntu), [Fedora](/docs/fedora), or [Arch](/docs/arch).
|
||||
|
||||
> New here? Read [Security & Safe Use](/docs/security) first — a streaming host is remote control of
|
||||
> the machine, so keep it on a trusted LAN or VPN and require pairing.
|
||||
|
||||
## host.env
|
||||
|
||||
Write `~/.config/punktfunk/host.env` with the GNOME settings. The host auto-detects the compositor
|
||||
from your session, so the explicit `PUNKTFUNK_COMPOSITOR` is belt-and-braces:
|
||||
|
||||
```ini
|
||||
# ~/.config/punktfunk/host.env
|
||||
WAYLAND_DISPLAY=wayland-0
|
||||
XDG_CURRENT_DESKTOP=GNOME
|
||||
PUNKTFUNK_COMPOSITOR=mutter
|
||||
PUNKTFUNK_VIDEO_SOURCE=virtual
|
||||
PUNKTFUNK_ZEROCOPY=1
|
||||
PUNKTFUNK_INPUT_BACKEND=libei
|
||||
```
|
||||
|
||||
You must be on a **Wayland** session (not X11), and Mutter must be **≥ 48**. See the
|
||||
[Configuration reference](/docs/configuration) for every option.
|
||||
|
||||
## The GL/EGL userspace
|
||||
|
||||
On NVIDIA, gnome-shell fails to start — or the host logs **"GPU … not supported by EGL"** — when the
|
||||
NVIDIA GL/EGL userspace is missing. The base driver package doesn't always pull it in. Install your
|
||||
distro's NVIDIA GL/EGL userspace package — on **Ubuntu/Debian** it's `libnvidia-gl-<version>` matching
|
||||
your driver; on **Fedora/Arch** it ships with the RPM Fusion / repo driver — then confirm the glvnd
|
||||
vendor file exists:
|
||||
|
||||
```sh
|
||||
ls /usr/share/glvnd/egl_vendor.d/10_nvidia.json # must exist
|
||||
```
|
||||
|
||||
Installing the driver itself is covered on your distro's install page
|
||||
([Ubuntu](/docs/ubuntu), [Fedora](/docs/fedora), [Arch](/docs/arch)).
|
||||
|
||||
## Do not lock the session
|
||||
|
||||
A **locked** GNOME session blocks screen capture — the host fails with
|
||||
**"Session creation inhibited"**. On an always-on or headless host there's no one to unlock it, so
|
||||
disable the lock:
|
||||
|
||||
```sh
|
||||
gsettings set org.gnome.desktop.screensaver lock-enabled false
|
||||
gsettings set org.gnome.desktop.session idle-delay 0
|
||||
```
|
||||
|
||||
## Start the host
|
||||
|
||||
With `host.env` in place, start the host from **inside your GNOME session**:
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-host
|
||||
journalctl --user -u punktfunk-host -f # watch it come up and print its identity fingerprint
|
||||
```
|
||||
|
||||
Then bring up [The Web Console](/docs/web-console) to arm pairing and connect a
|
||||
[client](/docs/clients). For an always-on box, see the [headless session](#headless-session) below.
|
||||
|
||||
## Headless session
|
||||
|
||||
To run with no monitor and no login, keep a GNOME Wayland session up at all times and start the host
|
||||
without a login. Have GDM auto-login your user:
|
||||
|
||||
```ini
|
||||
# /etc/gdm3/custom.conf (Ubuntu) · /etc/gdm/custom.conf (Fedora)
|
||||
[daemon]
|
||||
AutomaticLoginEnable = true
|
||||
AutomaticLogin = your-user
|
||||
```
|
||||
|
||||
Disable the lock (see [above](#do-not-lock-the-session)), then enable the host user service and let it
|
||||
linger past logout:
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-host
|
||||
sudo loginctl enable-linger "$USER"
|
||||
```
|
||||
|
||||
Reboot and the host comes up on the auto-login session. Full walkthrough:
|
||||
[Running as a Service](/docs/running-as-a-service).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
More fixes — black screen, discovery, pairing — in [Troubleshooting](/docs/troubleshooting).
|
||||
|
||||
Once the host is up, bring the console up and pair — see [The Web Console](/docs/web-console).
|
||||
@@ -68,4 +68,4 @@ LAN.
|
||||
## Multiple devices at once
|
||||
|
||||
A host can stream to several clients simultaneously — your laptop and your TV both viewing (and
|
||||
controlling) the desktop, each at its own resolution. See [Multiple devices](/docs/configuration#multiple-devices).
|
||||
controlling) the desktop, each at its own resolution. See [Multiple devices](/docs/configuration#multiple-devices-at-once).
|
||||
|
||||
@@ -29,7 +29,7 @@ It's built for the things that make streaming feel native:
|
||||
<Cards>
|
||||
<Card title="How It Works" href="/docs/how-it-works" description="The ideas behind punktfunk in a few minutes — virtual displays, the two protocols, pairing." />
|
||||
<Card title="Quick Start" href="/docs/quickstart" description="From nothing to streaming: set up a host and connect your first client." />
|
||||
<Card title="Host Setup" href="/docs/requirements" description="Install the host on Ubuntu (GNOME or KDE), Fedora (KDE), or Bazzite." />
|
||||
<Card title="Host Setup" href="/docs/requirements" description="Install on Ubuntu, Fedora, Arch, Bazzite, SteamOS, or Windows." />
|
||||
<Card title="Connect a Client" href="/docs/clients" description="Stream with the native app for your device — macOS, Linux, Windows, Android — or any Moonlight client." />
|
||||
<Card title="API Reference" href="/api" description="Interactive OpenAPI reference for the host's management REST API — status, devices, pairing, library." />
|
||||
</Cards>
|
||||
@@ -37,7 +37,7 @@ It's built for the things that make streaming feel native:
|
||||
## What you need
|
||||
|
||||
- A **host** with a supported GPU — either a **Linux** machine running one of the
|
||||
[supported setups](/docs/requirements) (**Ubuntu** GNOME or KDE, **Fedora** KDE, or **Bazzite**), or
|
||||
[supported setups](/docs/requirements) (**Ubuntu**, **Fedora**, **Arch**, or **Bazzite**), or
|
||||
a **[Windows](/docs/windows-host) PC**.
|
||||
- A **client device** to stream to — there are native apps for **macOS, iOS/iPadOS, tvOS, Linux,
|
||||
Windows, and Android**, plus any device that runs **Moonlight**.
|
||||
|
||||
@@ -16,9 +16,9 @@ On **Windows**, the host ships as a signed installer instead — see [Windows](#
|
||||
|
||||
| Distro | Package manager | One-command happy path | Guide |
|
||||
|--------|-----------------|------------------------|-------|
|
||||
| **Ubuntu / Debian** | apt | `sudo apt install punktfunk-host` | [Ubuntu — GNOME](/docs/ubuntu-gnome) · [Ubuntu — KDE](/docs/ubuntu-kde) · [packaging/debian](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/debian/README.md) |
|
||||
| **Ubuntu / Debian** | apt | `sudo apt install punktfunk-host` | [Ubuntu / Debian](/docs/ubuntu) · [packaging/debian](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/debian/README.md) |
|
||||
| **Bazzite / Fedora Atomic** | systemd-sysext | `sudo bash punktfunk-sysext.sh install` (no layering, no reboot) | [Bazzite](/docs/bazzite) · [packaging/bazzite](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/bazzite/README.md) |
|
||||
| **Fedora (dnf)** | dnf / rpm-ostree | `dnf install punktfunk punktfunk-web` | [Fedora — KDE](/docs/fedora-kde) · [packaging/rpm](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/rpm/README.md) |
|
||||
| **Fedora (dnf)** | dnf / rpm-ostree | `dnf install punktfunk punktfunk-web` | [Fedora](/docs/fedora) · [packaging/rpm](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/rpm/README.md) |
|
||||
| **Arch** | pacman | `pacman -Sy punktfunk-host` (binary repo) | [Arch Linux](/docs/arch) · [packaging/arch](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/arch/README.md) |
|
||||
| **SteamOS (host)** | on-device script | `bash scripts/steamdeck/install.sh` | [SteamOS (Host)](/docs/steamos-host) |
|
||||
|
||||
@@ -79,13 +79,22 @@ fallback without one. More detail — including the CLI `punktfunk-host service
|
||||
Bare `serve` is the secure native-only default (native `punktfunk/1` + the web console). On a
|
||||
trusted LAN, add `--gamestream` to also serve stock [Moonlight](/docs/moonlight) clients.
|
||||
|
||||
3. Enable the web console and read its login password, then open `http://<host-ip>:47992`:
|
||||
3. Enable the web console:
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-web
|
||||
journalctl --user -u punktfunk-web-init | sed -n 's/.*password generated: //p'
|
||||
```
|
||||
|
||||
Then open `http://<host-ip>:47992`. Reading its [login password](/docs/web-console#login-password)
|
||||
and [arming PIN pairing](/docs/web-console#arm-pairing) are covered in
|
||||
[The Web Console](/docs/web-console).
|
||||
|
||||
### Configure your desktop
|
||||
|
||||
How the virtual display and input work depends on your desktop — see [KDE](/docs/kde),
|
||||
[GNOME](/docs/gnome), [Steam / gamescope](/docs/gamescope), or [Sway](/docs/sway) for the
|
||||
compositor-specific setup.
|
||||
|
||||
From there, follow the [Quick Start](/docs/quickstart) to pair your first client. To run the host
|
||||
automatically at boot, see [Running as a Service](/docs/running-as-a-service).
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
---
|
||||
title: KDE Plasma (KWin)
|
||||
description: Configure a punktfunk host for KDE — host.env, quirks, and a headless KWin session.
|
||||
---
|
||||
|
||||
Configure a punktfunk host on **KDE Plasma**. The host uses KDE's KWin compositor to create a
|
||||
per-client virtual display, captured zero-copy on NVIDIA. This page assumes the package is already
|
||||
installed — see [Ubuntu](/docs/ubuntu), [Fedora](/docs/fedora), [Arch](/docs/arch), or the
|
||||
[Bazzite](/docs/bazzite) appliance.
|
||||
|
||||
> New here? Read [Security & Safe Use](/docs/security) first — a streaming host is remote control of
|
||||
> the machine, so keep it on a trusted LAN or VPN and require pairing.
|
||||
|
||||
## host.env
|
||||
|
||||
A KDE starter `~/.config/punktfunk/host.env`:
|
||||
|
||||
```ini
|
||||
WAYLAND_DISPLAY=wayland-0
|
||||
XDG_CURRENT_DESKTOP=KDE
|
||||
PUNKTFUNK_COMPOSITOR=kwin
|
||||
PUNKTFUNK_VIDEO_SOURCE=virtual
|
||||
PUNKTFUNK_ZEROCOPY=1
|
||||
PUNKTFUNK_INPUT_BACKEND=libei
|
||||
```
|
||||
|
||||
The host auto-detects the running compositor on every connect, so most of this is optional — the
|
||||
values above are just what it resolves to on a KWin session. See the
|
||||
[Configuration reference](/docs/configuration) for every option.
|
||||
|
||||
## Use a Wayland session
|
||||
|
||||
KDE must run on **Wayland**, not X11 — pick the Wayland session from the picker on the login screen.
|
||||
The virtual-display path is Wayland-only and will not come up under X11.
|
||||
|
||||
KWin must be **6.5.6 or newer** (virtual outputs land there). Check with:
|
||||
|
||||
```sh
|
||||
kwin_wayland --version
|
||||
```
|
||||
|
||||
## Streaming the interactive desktop
|
||||
|
||||
To stream a logged-in Plasma desktop (rather than a headless session, below), KWin has to hand the
|
||||
host its restricted screencast protocol. The host package ships an `io.unom.Punktfunk.Host.desktop`
|
||||
file whose `X-KDE-Wayland-Interfaces` grants exactly that on a normal interactive session
|
||||
(least-privilege, the same mechanism krfb/krdp use). After a **fresh install, log out and back into
|
||||
the Desktop session once** so KWin re-reads the grant.
|
||||
|
||||
A normal KDE login still lacks the RemoteDesktop grant that **input** injection needs — without it the
|
||||
host pops an "Allow remote control?" dialog no headless box can answer. **Fedora and Bazzite** ship a
|
||||
one-shot helper that seeds it (run once as the streaming user, no root):
|
||||
|
||||
```sh
|
||||
bash /usr/share/punktfunk/bazzite/kde-desktop-setup.sh # Fedora / Bazzite
|
||||
```
|
||||
|
||||
The `.deb` and Arch packages don't include that wrapper. Seed the grant by hand instead — copy the
|
||||
shipped `kde-authorized` file into the portal store (the share dir is `/usr/share/punktfunk-host` on
|
||||
Debian/Ubuntu, `/usr/share/punktfunk` on Arch), then log out and back in:
|
||||
|
||||
```sh
|
||||
mkdir -p ~/.local/share/flatpak/db
|
||||
cp /usr/share/punktfunk*/headless/kde-authorized ~/.local/share/flatpak/db/kde-authorized
|
||||
```
|
||||
|
||||
A login-less appliance skips all of this — its headless session (below) needs none of these grants.
|
||||
|
||||
## Start the host
|
||||
|
||||
With `host.env` in place, start the host from **inside your Plasma session**:
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-host
|
||||
journalctl --user -u punktfunk-host -f # watch it come up and print its identity fingerprint
|
||||
```
|
||||
|
||||
Then bring up [The Web Console](/docs/web-console) to arm pairing and connect a
|
||||
[client](/docs/clients). To start at boot — including fully headless — see the
|
||||
[headless session](#headless-session) below or [Running as a Service](/docs/running-as-a-service).
|
||||
|
||||
## Persistent per-client scaling
|
||||
|
||||
KWin round-trips per-client display scale: it names each session's virtual output per client, so a
|
||||
scale you set for one client (150 %, 125 %, …) is reapplied on that client's next connect. See
|
||||
[Virtual displays](/docs/virtual-displays).
|
||||
|
||||
## Headless session
|
||||
|
||||
For a login-less appliance — a box that streams at boot with no graphical login — the host brings up a
|
||||
**dedicated headless KWin session** rather than relying on an interactive one. It runs its own
|
||||
`kwin --virtual` session (shipped as the `punktfunk-kde-session.service` unit) with permission checks
|
||||
relaxed, so it needs none of the interactive grants above.
|
||||
|
||||
```sh
|
||||
mkdir -p ~/.config/punktfunk
|
||||
cp /usr/share/punktfunk/host.env.kde ~/.config/punktfunk/host.env # Debian/Ubuntu: /usr/share/punktfunk-host/host.env.kde
|
||||
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now punktfunk-kde-session punktfunk-host
|
||||
sudo loginctl enable-linger "$USER"
|
||||
```
|
||||
|
||||
The session unit brings up headless KWin; the host unit follows it and starts listening. See
|
||||
[Running as a Service](/docs/running-as-a-service) for the full headless setup.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **KWin too old:** virtual outputs need KWin **≥ 6.5.6**. Check with `kwin_wayland --version`.
|
||||
- **Black screen / no picture:** confirm you're on a Wayland session (not X11) and the NVIDIA GL
|
||||
userspace is installed. More in [Troubleshooting](/docs/troubleshooting).
|
||||
|
||||
To bring the console up and pair, see [The Web Console](/docs/web-console).
|
||||
@@ -5,27 +5,31 @@
|
||||
"how-it-works",
|
||||
"security",
|
||||
"quickstart",
|
||||
"install",
|
||||
"---Host Setup---",
|
||||
"---Install the host---",
|
||||
"requirements",
|
||||
"ubuntu-gnome",
|
||||
"ubuntu-kde",
|
||||
"fedora-kde",
|
||||
"install",
|
||||
"ubuntu",
|
||||
"fedora",
|
||||
"arch",
|
||||
"bazzite",
|
||||
"steamos-host",
|
||||
"windows-host",
|
||||
"web-console",
|
||||
"---Configure your desktop---",
|
||||
"configuration",
|
||||
"kde",
|
||||
"gnome",
|
||||
"gamescope",
|
||||
"sway",
|
||||
"running-as-a-service",
|
||||
"virtual-displays",
|
||||
"host-cli",
|
||||
"---Connecting---",
|
||||
"clients",
|
||||
"install-client",
|
||||
"steam-deck",
|
||||
"moonlight",
|
||||
"pairing",
|
||||
"---Configuration---",
|
||||
"configuration",
|
||||
"virtual-displays",
|
||||
"host-cli",
|
||||
"---Troubleshooting---",
|
||||
"troubleshooting",
|
||||
"stats",
|
||||
|
||||
@@ -11,15 +11,19 @@ This is the shortest path to a working stream. Each step links to the details.
|
||||
|
||||
## 1. Set up the host
|
||||
|
||||
On your Linux gaming machine (NVIDIA, AMD, or Intel GPU), follow the guide for your system:
|
||||
On your gaming machine (NVIDIA, AMD, or Intel GPU), follow the install guide for your system:
|
||||
|
||||
- [Ubuntu — GNOME](/docs/ubuntu-gnome)
|
||||
- [Ubuntu — KDE Plasma](/docs/ubuntu-kde)
|
||||
- [Fedora — KDE Plasma](/docs/fedora-kde)
|
||||
- [Bazzite — gamescope / Steam](/docs/bazzite)
|
||||
- [Ubuntu / Debian](/docs/ubuntu)
|
||||
- [Fedora](/docs/fedora)
|
||||
- [Arch](/docs/arch)
|
||||
- [Bazzite](/docs/bazzite)
|
||||
- [SteamOS](/docs/steamos-host)
|
||||
- [Windows host](/docs/windows-host)
|
||||
|
||||
Each one covers the GPU driver, the dependencies, and how to build and run the host. Check the
|
||||
[Requirements](/docs/requirements) first if you're not sure your machine is a fit.
|
||||
Each one covers the GPU driver, the dependencies, and how to install and run the host. After
|
||||
installing, configure for your desktop ([KDE](/docs/kde) / [GNOME](/docs/gnome) /
|
||||
[gamescope](/docs/gamescope) / [Sway](/docs/sway)). Check the [Requirements](/docs/requirements)
|
||||
first if you're not sure your machine is a fit.
|
||||
|
||||
## 2. Start the host
|
||||
|
||||
@@ -44,9 +48,9 @@ latency, or any Moonlight client:
|
||||
the list of hosts found on your network. Select it, and when prompted, **pair**.
|
||||
- **Anything with Moonlight:** add the host (it should be discovered automatically), then pair.
|
||||
|
||||
To pair, the host needs to show a PIN. Arm pairing from the host's web console — the host displays a
|
||||
4-digit PIN, you type it into the client, and they trust each other from then on. Pairing is required
|
||||
by default. Full details: [Pairing & Trust](/docs/pairing).
|
||||
To pair, the host needs to show a PIN. [Arm pairing](/docs/web-console#arm-pairing) from the host's
|
||||
web console — the host displays a 4-digit PIN, you type it into the client, and they trust each other
|
||||
from then on. Pairing is required by default. Full details: [Pairing & Trust](/docs/pairing).
|
||||
|
||||
## 4. Stream
|
||||
|
||||
|
||||
@@ -6,19 +6,31 @@ description: What you need to run a punktfunk host — GPU, driver, desktop, and
|
||||
## Supported setups
|
||||
|
||||
A punktfunk host runs primarily on a Linux machine with a dedicated GPU — NVIDIA (NVENC) is the
|
||||
most-exercised path, and AMD/Intel GPUs work via VAAPI (a native
|
||||
[Windows host](/docs/windows-host) is also available — see below). These are the Linux desktop
|
||||
environments it supports today, each with its own guide:
|
||||
most-exercised path, and AMD/Intel GPUs work via VAAPI. A native [Windows host](/docs/windows-host)
|
||||
is also available. Setup splits along two axes: you **install** the package per distro, then
|
||||
**configure** the host — and learn its quirks — per desktop/compositor.
|
||||
|
||||
| Setup | Desktop / compositor | Guide |
|
||||
|---|---|---|
|
||||
| **Ubuntu** (Desktop or Server) | GNOME (Mutter) | [Ubuntu — GNOME](/docs/ubuntu-gnome) |
|
||||
| **Ubuntu** (Desktop or Server) | KDE Plasma (KWin) | [Ubuntu — KDE](/docs/ubuntu-kde) |
|
||||
| **Fedora** | KDE Plasma (KWin) | [Fedora — KDE](/docs/fedora-kde) |
|
||||
| **Bazzite** | gamescope (Steam) | [Bazzite](/docs/bazzite) |
|
||||
> New here? Read [Security & Safe Use](/docs/security) first — a streaming host is remote control of
|
||||
> the machine, so keep it on a trusted LAN or VPN and require pairing.
|
||||
|
||||
Other wlroots compositors (Sway/Hyprland) also work but aren't a primary target. If your desktop isn't
|
||||
listed, the host still needs one of these compositor backends to create a virtual display.
|
||||
**Distros — install the package:**
|
||||
|
||||
- [Ubuntu / Debian](/docs/ubuntu)
|
||||
- [Fedora](/docs/fedora)
|
||||
- [Arch](/docs/arch)
|
||||
- [Bazzite](/docs/bazzite)
|
||||
- [SteamOS](/docs/steamos-host)
|
||||
|
||||
**Desktops — configure and quirks:**
|
||||
|
||||
- [KDE Plasma (KWin)](/docs/kde)
|
||||
- [GNOME (Mutter)](/docs/gnome)
|
||||
- [Steam / gamescope](/docs/gamescope)
|
||||
- [Sway / wlroots](/docs/sway)
|
||||
|
||||
Pick your distro to install, then your desktop to configure — the two are independent. Other
|
||||
wlroots compositors (Hyprland) work but aren't a primary target; the host still needs one of these
|
||||
compositor backends to create a virtual display.
|
||||
|
||||
> **Windows host:** punktfunk also runs as a native host on **Windows 11 22H2 or newer (x64)** — a
|
||||
> signed installer that registers a service and bundles a virtual-display driver (whose driver-
|
||||
@@ -32,8 +44,8 @@ listed, the host still needs one of these compositor backends to create a virtua
|
||||
encodes the video in hardware.
|
||||
- **NVIDIA driver 535 or newer** (550+ recommended). The driver must include the **GL/EGL userspace**,
|
||||
not just `nvidia-utils` — without it the compositor can't initialise the GPU and capture fails. Each
|
||||
setup guide installs the right package (e.g. `libnvidia-gl-<version>` on Ubuntu).
|
||||
- **`nvidia-drm modeset=1`** must be enabled (Wayland on NVIDIA needs it). The setup guides cover this.
|
||||
install guide installs the right package (e.g. `libnvidia-gl-<version>` on Ubuntu).
|
||||
- **`nvidia-drm modeset=1`** must be enabled (Wayland on NVIDIA needs it). The install guides cover this.
|
||||
- **AMD / Intel GPUs** encode via **VAAPI** instead (install `mesa-va-drivers` or
|
||||
`intel-media-driver`; validated live on AMD RDNA3). The NVIDIA-specific notes above don't apply
|
||||
there. On modern Intel (Gen12/Tiger Lake and newer, including Arc) the driver only offers the
|
||||
@@ -57,9 +69,9 @@ needs to be running for the user the host runs as. This can be:
|
||||
|
||||
Minimum compositor versions (newer is fine):
|
||||
|
||||
- **KWin ≥ 6.5.6** (KDE Plasma) — headless virtual outputs.
|
||||
- **GNOME ≥ 48** (Mutter) — virtual-monitor screen-cast.
|
||||
- **gamescope ≥ 3.16.22** (Bazzite/Steam) — older versions deadlock during capture.
|
||||
- **KWin ≥ 6.5.6** ([KDE Plasma](/docs/kde)) — headless virtual outputs.
|
||||
- **GNOME ≥ 48** ([Mutter](/docs/gnome)) — virtual-monitor screen-cast.
|
||||
- **gamescope ≥ 3.16.22** ([Bazzite/Steam](/docs/gamescope)) — older versions deadlock during capture.
|
||||
|
||||
## Network
|
||||
|
||||
@@ -70,10 +82,6 @@ Minimum compositor versions (newer is fine):
|
||||
- For best results, a wired or fast Wi-Fi link. The host can run a built-in **speed test** to pick a
|
||||
bitrate for your link (see [Configuration](/docs/configuration)).
|
||||
|
||||
> **Before you set up a host, read [Security & Safe Use](/docs/security).** A streaming host is
|
||||
> remote control of the machine — it's important to understand what that exposes, why to keep it on a
|
||||
> trusted network, and how pairing protects you.
|
||||
|
||||
## A client
|
||||
|
||||
You also need something to stream *to* — see [Connect a Client](/docs/clients). There are native
|
||||
|
||||
@@ -37,50 +37,21 @@ Start by making the host service start at boot even when nobody logs in:
|
||||
sudo loginctl enable-linger "$USER"
|
||||
```
|
||||
|
||||
Then bring up a session automatically, depending on your desktop:
|
||||
Then bring up a session automatically. How you do that is desktop-specific — auto-login, lock
|
||||
disable, and the session unit differ per compositor, so each is documented on its own page:
|
||||
|
||||
### Headless GNOME
|
||||
- GNOME: [GNOME → Headless session](/docs/gnome#headless-session).
|
||||
- KDE Plasma: [KDE → Headless session](/docs/kde#headless-session).
|
||||
- Steam / gamescope: [gamescope](/docs/gamescope) — the host launches its own session per client, so
|
||||
there's no separate session unit.
|
||||
|
||||
Have GDM auto-login your user, so a GNOME Wayland session is always running:
|
||||
|
||||
```ini
|
||||
# /etc/gdm3/custom.conf (Ubuntu) · /etc/gdm/custom.conf (Fedora)
|
||||
[daemon]
|
||||
AutomaticLoginEnable = true
|
||||
AutomaticLogin = your-user
|
||||
```
|
||||
|
||||
Then **disable the screen lock** — a locked GNOME session blocks screen capture, and there's no one to
|
||||
unlock a headless box:
|
||||
|
||||
```sh
|
||||
gsettings set org.gnome.desktop.screensaver lock-enabled false
|
||||
gsettings set org.gnome.desktop.session idle-delay 0
|
||||
```
|
||||
|
||||
Enable the host user service (section A) and reboot. The host comes up on the auto-login session.
|
||||
|
||||
### Headless KDE
|
||||
|
||||
punktfunk ships a unit that brings up a headless KWin/Plasma session with no display manager, so the
|
||||
host has a desktop to stream even with no monitor attached:
|
||||
|
||||
```sh
|
||||
cp scripts/punktfunk-kde-session.service scripts/punktfunk-host.service ~/.config/systemd/user/
|
||||
# host.env: PUNKTFUNK_COMPOSITOR=kwin, WAYLAND_DISPLAY=wayland-kde
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable punktfunk-kde-session punktfunk-host
|
||||
sudo loginctl enable-linger "$USER"
|
||||
reboot
|
||||
```
|
||||
|
||||
The session unit starts headless KWin; the host unit follows it and starts listening. (KWin only needs
|
||||
to be up by the time a client connects, so the ordering is soft.)
|
||||
Once a session comes up at boot, enable the host user service (section A) and reboot. The host comes up
|
||||
on that session.
|
||||
|
||||
### Headless Bazzite
|
||||
|
||||
On Bazzite, the host launches its own gamescope/Steam session per client, so you don't need a separate
|
||||
session unit — see [Bazzite](/docs/bazzite).
|
||||
session unit — see [Bazzite](/docs/bazzite) and [gamescope](/docs/gamescope).
|
||||
|
||||
## Windows
|
||||
|
||||
|
||||
@@ -86,9 +86,8 @@ When it finishes it prints the web-console URL and how to pair.
|
||||
|
||||
By default the host **requires PIN pairing** (secure). Two ways to pair:
|
||||
|
||||
- **Web console** (printed at the end of step 2): open `http://<device-ip>:47992`, log in with the
|
||||
generated password (in `~/.config/punktfunk/web.env`), go to **Devices → arm pairing**, and enter
|
||||
the PIN on your client.
|
||||
- **Web console** (printed at the end of step 2): open `http://<device-ip>:47992`,
|
||||
[arm pairing](/docs/web-console#arm-pairing), and enter the PIN on your client.
|
||||
- **From the client directly**: pick this host (it advertises over mDNS as `_punktfunk._udp`) and
|
||||
enter the PIN the host shows.
|
||||
|
||||
@@ -96,17 +95,9 @@ On a trusted home LAN you can instead install with `--open` and skip pairing ent
|
||||
|
||||
### Console login password
|
||||
|
||||
The installer generates a random console login password and writes it to
|
||||
`~/.config/punktfunk/web.env` (as `PUNKTFUNK_UI_PASSWORD=…`); it's also printed at the end of the
|
||||
install run (step 2). Read it back with:
|
||||
|
||||
```sh
|
||||
sed -n 's/^PUNKTFUNK_UI_PASSWORD=//p' ~/.config/punktfunk/web.env
|
||||
```
|
||||
|
||||
To set your own password, edit that file 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?](/docs/forgot-password).
|
||||
The installer generates a random console login password (printed at the end of step 2) and writes it
|
||||
to `~/.config/punktfunk/web.env`. To read it back or set your own, see
|
||||
[The Web Console](/docs/web-console#login-password).
|
||||
|
||||
## 4. Verify
|
||||
|
||||
@@ -118,7 +109,8 @@ journalctl --user -u punktfunk-host -f # watch a client connect
|
||||
Connect from a [native client](/docs/clients), or from [Moonlight](/docs/moonlight) (unless you
|
||||
installed with `--no-gamestream`). In Game Mode the host attaches to the running gamescope session and
|
||||
streams it at your client's resolution; in Desktop Mode it streams the KDE desktop. The host
|
||||
auto-detects which session is live per connection.
|
||||
auto-detects which session is live per connection. See [Steam / gamescope](/docs/gamescope) for the
|
||||
attach-vs-managed detail and known limits.
|
||||
|
||||
## Updating
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: Sway / wlroots
|
||||
description: Configure a punktfunk host on a wlroots compositor (Sway, Hyprland).
|
||||
---
|
||||
|
||||
The wlroots family can host — but **Sway is the only validated path.** The host adds a per-client
|
||||
headless output at the client's exact mode and captures it through the xdg-desktop-portal-wlr (xdpw)
|
||||
ScreenCast portal, injecting input via the wlroots virtual pointer/keyboard protocols. Hyprland and
|
||||
other wlroots compositors are best-effort (see [How it works](#how-it-works) for the caveat).
|
||||
|
||||
This is **not a primary target.** It works and is validated live on **sway 1.11** (zero-copy), but it
|
||||
sees far less testing than the KDE and GNOME paths — expect rougher edges. If you have a choice,
|
||||
[KDE](/docs/kde) or [GNOME](/docs/gnome) are the better-exercised desktops.
|
||||
|
||||
This page assumes the package is already installed — see [Arch](/docs/arch), [Ubuntu](/docs/ubuntu),
|
||||
or [Fedora](/docs/fedora).
|
||||
|
||||
> New here? Read [Security & Safe Use](/docs/security) first — a streaming host is remote control of
|
||||
> the machine, so keep it on a trusted LAN or VPN and require pairing.
|
||||
|
||||
## host.env
|
||||
|
||||
The host auto-detects a wlroots session, so you usually need nothing here. To force the backend, set
|
||||
these in `~/.config/punktfunk/host.env`:
|
||||
|
||||
```ini
|
||||
PUNKTFUNK_COMPOSITOR=wlroots # aliases: sway, hyprland
|
||||
PUNKTFUNK_INPUT_BACKEND=wlr
|
||||
PUNKTFUNK_VIDEO_SOURCE=virtual
|
||||
PUNKTFUNK_ZEROCOPY=1 # GPU zero-copy capture→encode; auto-falls back to CPU
|
||||
```
|
||||
|
||||
See [Configuration](/docs/configuration) for the full reference.
|
||||
|
||||
## How it works
|
||||
|
||||
- **Video** — the host adds a headless output at the client's exact mode with `swaymsg create_output`.
|
||||
This uses Sway's IPC specifically; other wlroots compositors (Hyprland, …) don't expose an
|
||||
equivalent, so virtual-output creation isn't wired up for them yet — Sway is the supported wlroots
|
||||
path today.
|
||||
- **Capture** — it captures that output through the **xdg-desktop-portal-wlr (xdpw)** ScreenCast
|
||||
portal. The host writes a managed chooser config so the output pick is automatic — no interactive
|
||||
picker dialog to answer.
|
||||
- **Input** — mouse and keyboard are injected via the wlroots **virtual pointer** and **virtual
|
||||
keyboard** protocols.
|
||||
|
||||
For how long the virtual output lives, and extend-vs-exclusive topology, see
|
||||
[Virtual displays](/docs/virtual-displays).
|
||||
|
||||
## Requirements
|
||||
|
||||
- A running wlroots session (Sway, Hyprland, …).
|
||||
- **xdg-desktop-portal-wlr (xdpw)** installed and running — the host captures through its ScreenCast
|
||||
portal. Without it there is no video.
|
||||
|
||||
## Start the host
|
||||
|
||||
With the backend selected, start the host from **inside your Sway session**:
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-host
|
||||
journalctl --user -u punktfunk-host -f
|
||||
```
|
||||
|
||||
## Bring up the console and pair
|
||||
|
||||
Enable the web console, read its login password, and arm PIN pairing — see
|
||||
[The Web Console](/docs/web-console). Then [connect a client](/docs/clients).
|
||||
@@ -71,10 +71,14 @@ The NVIDIA **GL/EGL userspace** is missing — the base driver package doesn't a
|
||||
- **Ubuntu:** `sudo apt install libnvidia-gl-<version>` (matching your driver).
|
||||
- Confirm `/usr/share/glvnd/egl_vendor.d/10_nvidia.json` exists and `nvidia-drm modeset` is `Y`.
|
||||
|
||||
See [GNOME](/docs/gnome) for the GL/EGL userspace details.
|
||||
|
||||
## Black screen / no picture, but the client connects
|
||||
|
||||
- You must be on a **Wayland** session, not X11 (check the login-screen session picker).
|
||||
- KWin must be **≥ 6.5.6** (`kwin_wayland --version`); GNOME **≥ 48**; gamescope **≥ 3.16.22**.
|
||||
- KWin must be **≥ 6.5.6** (`kwin_wayland --version`); GNOME **≥ 48**; gamescope **≥ 3.16.22**. See
|
||||
[KDE](/docs/kde) for the KWin/Wayland requirement and [gamescope](/docs/gamescope) for the
|
||||
gamescope one.
|
||||
- Confirm `PUNKTFUNK_COMPOSITOR` in [`host.env`](/docs/configuration) matches your desktop.
|
||||
|
||||
## Capture fails: "Session creation inhibited" (GNOME)
|
||||
@@ -86,7 +90,8 @@ gsettings set org.gnome.desktop.screensaver lock-enabled false
|
||||
gsettings set org.gnome.desktop.session idle-delay 0
|
||||
```
|
||||
|
||||
See [Running as a Service](/docs/running-as-a-service).
|
||||
See [GNOME → Headless session](/docs/gnome#headless-session) and
|
||||
[Running as a Service](/docs/running-as-a-service).
|
||||
|
||||
## A controller is detected but does nothing (Bazzite)
|
||||
|
||||
@@ -96,7 +101,8 @@ The host user needs to be in the `input` group. On Bazzite:
|
||||
ujust add-user-to-input-group
|
||||
```
|
||||
|
||||
Then log out and back in. On other distros this is `sudo usermod -aG input $USER` + re-login.
|
||||
Then log out and back in. On other distros this is `sudo usermod -aG input $USER` + re-login. See
|
||||
[Bazzite](/docs/bazzite).
|
||||
|
||||
## Pairing is rejected / the client can't connect
|
||||
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
---
|
||||
title: Ubuntu / Debian
|
||||
description: Install the punktfunk host on Ubuntu or Debian with apt.
|
||||
---
|
||||
|
||||
Install a punktfunk host on **Ubuntu** (Desktop or Server) or **Debian** from the apt registry. This
|
||||
page covers the distro-level setup — GPU driver, package, gamepad access. It works with either GNOME
|
||||
or KDE; how the host creates its virtual display and injects input is desktop-specific, so pick your
|
||||
desktop on the [configure pages](#configure-your-desktop) afterward rather than here.
|
||||
|
||||
> New here? Read [Security & Safe Use](/docs/security) first — a streaming host is remote control of
|
||||
> the machine, so keep it on a trusted LAN or VPN and require pairing.
|
||||
|
||||
## 1. GPU driver
|
||||
|
||||
On **NVIDIA**, install the recommended driver:
|
||||
|
||||
```sh
|
||||
sudo ubuntu-drivers install # or: sudo apt install nvidia-driver-<version>
|
||||
```
|
||||
|
||||
Then make sure the **GL/EGL userspace** is present — Wayland compositors on NVIDIA need it, and the
|
||||
base driver package doesn't always pull it in. Install the `libnvidia-gl` package matching your
|
||||
driver version:
|
||||
|
||||
```sh
|
||||
sudo apt install libnvidia-gl-<version> # e.g. libnvidia-gl-550
|
||||
```
|
||||
|
||||
Reboot, then confirm the driver and KMS modeset:
|
||||
|
||||
```sh
|
||||
nvidia-smi
|
||||
cat /sys/module/nvidia_drm/parameters/modeset # should print Y
|
||||
```
|
||||
|
||||
If modeset is not `Y`:
|
||||
|
||||
```sh
|
||||
echo 'options nvidia-drm modeset=1' | sudo tee /etc/modprobe.d/nvidia-drm.conf
|
||||
sudo update-initramfs -u && sudo reboot
|
||||
```
|
||||
|
||||
> **Secure Boot:** on a machine with Secure Boot **enabled**, the NVIDIA kernel module won't load
|
||||
> until you enrol its signing key. If `nvidia-smi` reports it can't talk to the driver, run
|
||||
> `sudo mokutil --import /var/lib/shim-signed/mok/MOK.der` (set a one-time password), reboot, and
|
||||
> choose **Enrol MOK** at the blue screen. Or disable Secure Boot in firmware.
|
||||
|
||||
On **AMD/Intel** none of the NVIDIA steps apply. Encode runs through VAAPI on the Mesa stack —
|
||||
`mesa-va-drivers` on AMD, `intel-media-driver` on Intel — which your desktop install already provides.
|
||||
|
||||
## 2. Install the host (apt)
|
||||
|
||||
`punktfunk-host` is published as a `.deb` to the public Gitea apt registry, so the box installs and
|
||||
updates with plain `apt`. The registry is public — no auth needed, just trust its signing key:
|
||||
|
||||
```sh
|
||||
sudo install -d -m 0755 /etc/apt/keyrings
|
||||
curl -fsSL https://git.unom.io/api/packages/unom/debian/repository.key \
|
||||
| sudo tee /etc/apt/keyrings/punktfunk.asc >/dev/null
|
||||
|
||||
echo "deb [signed-by=/etc/apt/keyrings/punktfunk.asc] https://git.unom.io/api/packages/unom/debian stable main" \
|
||||
| sudo tee /etc/apt/sources.list.d/punktfunk.list
|
||||
|
||||
sudo apt update
|
||||
sudo apt install punktfunk-host
|
||||
```
|
||||
|
||||
`punktfunk-host` `Recommends` the browser console (`punktfunk-web`), so apt pulls it in by default.
|
||||
The desktop *client* (`punktfunk-client`) is a separate package for the machine you stream *to* — not
|
||||
installed on a host. The NVIDIA driver is **not** a dependency — you installed it out of band in
|
||||
step 1. Later updates are just `sudo apt update && sudo apt upgrade`.
|
||||
|
||||
The `stable` component above is the stable channel. To track pre-release builds instead, see
|
||||
[Release Channels](/docs/channels).
|
||||
|
||||
## 3. Grant gamepad access
|
||||
|
||||
Virtual gamepads inject through `/dev/uinput`, which is gated by the `input` group. Add yourself and
|
||||
re-login so the new group membership takes effect:
|
||||
|
||||
```sh
|
||||
sudo usermod -aG input "$USER" # re-login to apply
|
||||
```
|
||||
|
||||
## Configure your desktop
|
||||
|
||||
How the host creates its virtual display and injects input depends on your desktop, not your distro.
|
||||
Continue on the page for the desktop you run — it covers your `host.env`, any compositor quirks, and
|
||||
starting the host:
|
||||
|
||||
- [KDE Plasma (KWin)](/docs/kde)
|
||||
- [GNOME (Mutter)](/docs/gnome)
|
||||
- [Steam / gamescope](/docs/gamescope)
|
||||
- [Sway / wlroots](/docs/sway)
|
||||
|
||||
Then bring up [The Web Console](/docs/web-console) to arm pairing and connect your first
|
||||
[client](/docs/clients). To run the host at boot — including fully **headless** — see
|
||||
[Running as a Service](/docs/running-as-a-service).
|
||||
|
||||
## Appendix — build from source
|
||||
|
||||
If the apt registry doesn't have a build for your release, or you want to track `main` directly,
|
||||
compile the host yourself (no clean updates / no packaged units — you wire those up by hand).
|
||||
|
||||
Install the build toolchain and runtime libraries:
|
||||
|
||||
```sh
|
||||
sudo apt install build-essential pkg-config cmake clang libclang-dev nasm git curl \
|
||||
pipewire pipewire-pulse wireplumber libpipewire-0.3-dev libspa-0.2-dev \
|
||||
libwayland-dev wayland-protocols libxkbcommon-dev libopus-dev \
|
||||
libdrm-dev libgbm-dev libegl-dev libgles-dev mesa-common-dev libva-dev \
|
||||
ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavfilter-dev libavdevice-dev \
|
||||
libnvidia-egl-wayland1 libnvidia-egl-gbm1 libei-dev
|
||||
```
|
||||
|
||||
Install Rust if you don't have it, then build:
|
||||
|
||||
```sh
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
git clone https://git.unom.io/unom/punktfunk.git && cd punktfunk
|
||||
cargo build --release -p punktfunk-host
|
||||
```
|
||||
|
||||
The host binary lands at `target/release/punktfunk-host`. Configure your desktop as above, then run
|
||||
it from inside your session:
|
||||
|
||||
```sh
|
||||
cargo run --release -p punktfunk-host -- serve --gamestream
|
||||
```
|
||||
|
||||
(The native plane is always on; `--gamestream` adds the Moonlight-compat surface — trusted LAN only.
|
||||
Drop it for a secure native-only host.)
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: The Web Console
|
||||
description: Enable the punktfunk browser console, read or change its login password, and arm PIN pairing.
|
||||
---
|
||||
|
||||
The web console is the browser UI for a punktfunk host — live status, paired devices, and the PIN
|
||||
pairing flow. It ships as the **`punktfunk-web`** systemd user unit on Linux and the **`PunktfunkWeb`**
|
||||
task on Windows, and serves on **`http://<host-ip>:47992`**. The host's own management API stays
|
||||
loopback-only behind it, so the console is the one surface you expose on the LAN.
|
||||
|
||||
> New here? Read [Security & Safe Use](/docs/security) first — a streaming host is remote control of
|
||||
> the machine, so keep it on a trusted LAN or VPN and require pairing.
|
||||
|
||||
## Enable the console
|
||||
|
||||
- **Linux packages (apt / RPM / Bazzite):** `punktfunk-host` recommends `punktfunk-web`, so your
|
||||
package manager pulls it in. Enable and start it as your desktop user, then open the URL:
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-web
|
||||
# then browse to http://<host-ip>:47992
|
||||
```
|
||||
|
||||
- **Windows host:** the installer sets up the console, its runtime, and the `PunktfunkWeb` task and
|
||||
starts it at boot. There is nothing to enable — open `http://<this-PC>:47992`.
|
||||
|
||||
- **SteamOS host:** the install script builds and starts the console as a user service for you. It
|
||||
prints the URL when it finishes.
|
||||
|
||||
## Login password
|
||||
|
||||
The console is password-protected. Where that password lives and how you change it depends on the
|
||||
host platform.
|
||||
|
||||
**Linux packages (apt / RPM / Bazzite).** On first start `punktfunk-web-init` generates a random
|
||||
password and saves it to `~/.config/punktfunk/web-password` (as `PUNKTFUNK_UI_PASSWORD=…`). Read it
|
||||
back from the init service's journal or straight from the file:
|
||||
|
||||
```sh
|
||||
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, edit that file (`PUNKTFUNK_UI_PASSWORD=<your-password>`) and restart the console:
|
||||
`systemctl --user restart punktfunk-web`.
|
||||
|
||||
**SteamOS host.** Same idea, but the install script writes the generated password to
|
||||
`~/.config/punktfunk/web.env` and prints it at the end of the install run:
|
||||
|
||||
```sh
|
||||
sed -n 's/^PUNKTFUNK_UI_PASSWORD=//p' ~/.config/punktfunk/web.env
|
||||
```
|
||||
|
||||
Edit that file and `systemctl --user restart punktfunk-web` to change it.
|
||||
|
||||
**Windows host.** You choose the password during install — a secure random default is pre-filled and
|
||||
shown again on the installer's final page. It's stored in `%ProgramData%\punktfunk\web-password` (as
|
||||
`PUNKTFUNK_UI_PASSWORD=…`), readable only by Administrators and SYSTEM. To change it, edit the file
|
||||
and restart the task in an **elevated** PowerShell:
|
||||
|
||||
```powershell
|
||||
notepad "$env:ProgramData\punktfunk\web-password" # set PUNKTFUNK_UI_PASSWORD=<your-password>
|
||||
schtasks /End /TN PunktfunkWeb; schtasks /Run /TN PunktfunkWeb
|
||||
```
|
||||
|
||||
Forgot it? See [Forgot your Password?](/docs/forgot-password).
|
||||
|
||||
## Arm pairing
|
||||
|
||||
The host **requires PIN pairing** by default (secure on a LAN). To connect the first time, open the
|
||||
console, log in, and go to **Devices → arm pairing**. The host displays a 4-digit PIN — enter it on
|
||||
your [client](/docs/clients) to pair. See [Pairing & Trust](/docs/pairing) for the full trust model
|
||||
and how to approve or remove devices later.
|
||||
@@ -59,29 +59,24 @@ Packaging internals live in
|
||||
|
||||
### Web console & pairing
|
||||
|
||||
See [The Web Console](/docs/web-console) for the console + pairing model shared with the Linux host;
|
||||
the Windows specifics follow.
|
||||
|
||||
The installer also sets up the **web management console** (status, paired devices, the PIN pairing
|
||||
flow): it bundles the console plus its own runtime and runs it as the **`PunktfunkWeb`** task on
|
||||
**`http://<this-PC>:47992`**, starting at boot.
|
||||
|
||||
#### Console login password
|
||||
|
||||
During setup you choose the console **login password** — it's pre-filled with a secure random default
|
||||
and shown again on the installer's final page. It's stored in `%ProgramData%\punktfunk\web-password`
|
||||
(as `PUNKTFUNK_UI_PASSWORD=…`), readable only by Administrators and SYSTEM.
|
||||
|
||||
To change it, edit that file and restart the console task. In an **elevated** PowerShell:
|
||||
|
||||
```powershell
|
||||
notepad "$env:ProgramData\punktfunk\web-password" # set PUNKTFUNK_UI_PASSWORD=<your-password>
|
||||
schtasks /End /TN PunktfunkWeb; schtasks /Run /TN PunktfunkWeb
|
||||
```
|
||||
|
||||
Forgot it? This is the recovery path linked from the console login screen — see
|
||||
You choose the console **login password** during setup — a secure random default is pre-filled and
|
||||
shown on the installer's final page. It's stored in `%ProgramData%\punktfunk\web-password`, readable
|
||||
only by Administrators and SYSTEM. To read or change it (with the `schtasks` restart), see
|
||||
[The Web Console → Login password](/docs/web-console#login-password); forgot it entirely?
|
||||
[Forgot your Password?](/docs/forgot-password).
|
||||
|
||||
The host **requires PIN pairing** by default (secure on a LAN). To connect the first time, open the
|
||||
console from any browser on the LAN, log in, go to **Devices → arm pairing**, and enter the PIN on
|
||||
your [client](/docs/clients). The host's own management API stays loopback-only behind the console.
|
||||
console from any browser on the LAN, log in, go to **Devices → [arm pairing](/docs/web-console#arm-pairing)**,
|
||||
and enter the PIN on your [client](/docs/clients). The host's own management API stays loopback-only behind the console.
|
||||
|
||||
### Configure
|
||||
|
||||
|
||||
Reference in New Issue
Block a user