docs(dist): end-user install front door + serve/pairing/firewall accuracy fixes
Make the host docs match the real distribution path and the actual CLI. Reviewed by a multi-agent pass (6 editors against one verified fact sheet + an accuracy reviewer); its findings (a wrong client-Recommends claim, a native-concurrency overstatement) folded in. - Install front door: new README "Install (host)" method-picker + docs-site/install.md (+ nav), routing each distro to its package registry; source build demoted to a fallback. - Registry-first install: ubuntu-gnome/ubuntu-kde now lead with the apt registry (not a cargo build); bazzite leads with the Gitea RPM registry (was COPR/source). Source builds moved to an appendix. - CLI accuracy: serve --native arms pairing from the web console (NOT --allow-pairing, which with --require-pairing/--max-concurrent is m3-host-only); --open disables mandatory pairing. host-cli/configuration/pairing/quickstart/troubleshooting corrected; mgmt API documented as always HTTPS+token. Native host serves one session at a time (extras queue) — not multi. - Firewall: real ports documented (native UDP 9777 + the ephemeral data port caveat + GameStream ports) for Debian + Arch (ufw + nftables), not just Bazzite. - Sync/accuracy: punktfunk-client (GTK4) presented as a shipping client (not "roadmap"), punktfunk-client-rs as the headless tool; host Recommends punktfunk-web only (not the client); COPR chroots f43/44; bootc header says Gitea registry not COPR. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,10 +13,37 @@ the mode of the device you're streaming to, not the TV the box is plugged into.
|
||||
|
||||
## Install
|
||||
|
||||
The host installs from the punktfunk COPR repository (see `packaging/bazzite/` in the repo for the
|
||||
exact COPR/RPM/bootc options). You can also build from source as on
|
||||
[Fedora KDE](/docs/fedora-kde) — Bazzite is Fedora Atomic underneath, and its FFmpeg builds the host
|
||||
fine.
|
||||
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:
|
||||
|
||||
```sh
|
||||
# Add the repo. Our RPMs are unsigned, but Gitea GPG-signs the repo METADATA — verify that
|
||||
# (repo_gpgcheck=1) and skip the per-package signature check (gpgcheck=0). The signed metadata
|
||||
# carries each package's SHA256, so authenticity still holds. (Don't curl Gitea's served
|
||||
# bazzite.repo verbatim — it sets gpgcheck=1, which fails on unsigned packages.)
|
||||
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=0
|
||||
repo_gpgcheck=1
|
||||
gpgkey=https://git.unom.io/api/packages/unom/rpm/repository.key
|
||||
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](/docs/fedora-kde)), but the registry is the supported path.
|
||||
|
||||
## Allow controller input
|
||||
|
||||
@@ -32,7 +59,14 @@ permission, not a client problem.)
|
||||
|
||||
## Configure
|
||||
|
||||
Point the host at the gamescope backend in `~/.config/punktfunk/host.env`:
|
||||
The RPM ships a gamescope-ready config you can copy as your starting point:
|
||||
|
||||
```sh
|
||||
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:
|
||||
|
||||
```sh
|
||||
PUNKTFUNK_COMPOSITOR=gamescope
|
||||
@@ -51,6 +85,14 @@ Bazzite hosts are typically headless. Enable the host service and linger so it s
|
||||
[Running as a Service](/docs/running-as-a-service). Because the host launches its own gamescope
|
||||
session per client, you don't need a separate desktop-session unit.
|
||||
|
||||
```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>:3000:
|
||||
systemctl --user enable --now punktfunk-web
|
||||
journalctl --user -u punktfunk-web-init | sed -n 's/.*password generated: //p'
|
||||
```
|
||||
|
||||
## Good to know
|
||||
|
||||
- **gamescope 3.16.22 or newer is required.** Older versions can deadlock during capture. Bazzite's
|
||||
|
||||
@@ -3,7 +3,8 @@ title: Clients
|
||||
description: The ways to connect to a punktfunk host — the Apple app, Moonlight, or the Linux client.
|
||||
---
|
||||
|
||||
A punktfunk host accepts two kinds of client. Pick whichever fits the device you're streaming *to*.
|
||||
A punktfunk host accepts clients over its own `punktfunk/1` protocol (the Apple and Linux apps) and
|
||||
over GameStream (Moonlight). Pick whichever fits the device you're streaming *to*.
|
||||
|
||||
## Apple app (Mac, iPhone, iPad, Apple TV)
|
||||
|
||||
@@ -28,24 +29,49 @@ software. See [Connect with Moonlight](/docs/moonlight).
|
||||
This is the broadest-compatibility option and great for couch gaming. It doesn't use the native
|
||||
protocol's FEC/encryption extensions, but for a healthy LAN that rarely matters.
|
||||
|
||||
## Linux reference client
|
||||
## Linux desktop client (GTK4)
|
||||
|
||||
`punktfunk-client-rs` (in the repo) is a command-line client for the native protocol, mainly for
|
||||
testing and development. It connects, streams to a file, runs the speed test, and can discover hosts:
|
||||
`punktfunk-client` is the native graphical Linux client — a GTK4 / libadwaita app that speaks
|
||||
`punktfunk/1` directly, with hardware decode (VAAPI → dmabuf on Intel/AMD, software fallback),
|
||||
PipeWire audio, and SDL3 controllers (rumble, lightbar, DualSense touchpad/motion). Like the Apple
|
||||
app it discovers hosts on your network automatically, does PIN pairing, and pins reconnects.
|
||||
|
||||
It ships as a real package, not just a source build:
|
||||
|
||||
- **Ubuntu / Debian** — `apt install punktfunk-client` from the punktfunk apt registry
|
||||
(see `packaging/debian/README.md`).
|
||||
- **Fedora / Bazzite** — `rpm-ostree install punktfunk-client` from the Gitea RPM registry
|
||||
(see `packaging/rpm/README.md`).
|
||||
- **Arch / SteamOS** — the `punktfunk-client` split package from the `PKGBUILD`
|
||||
(see `packaging/arch/README.md`).
|
||||
- **Steam Deck / any Flatpak distro** — the `io.unom.Punktfunk` Flatpak bundle
|
||||
(see `packaging/flatpak/README.md`); this is what the Decky plugin launches.
|
||||
|
||||
Launch it, pick your host from the list, and stream. For scripting you can skip the host list and
|
||||
connect straight away:
|
||||
|
||||
```sh
|
||||
punktfunk-client-rs --discover # list hosts on the network
|
||||
punktfunk-client-rs --connect <host>:9777 --pin <fp> # connect to one
|
||||
punktfunk-client --connect <host>:9777 # skip the picker, start a session immediately
|
||||
```
|
||||
|
||||
A full graphical Linux client (hardware decode + present) is on the [roadmap](/docs/roadmap).
|
||||
## Linux reference client (headless)
|
||||
|
||||
`punktfunk-client-rs` (in the repo) is a command-line client for the native protocol, used for
|
||||
testing, development, and latency measurement — not an everyday client. It connects, streams to a
|
||||
file, runs the speed test, and can discover hosts:
|
||||
|
||||
```sh
|
||||
punktfunk-client-rs --discover # list hosts on the network
|
||||
punktfunk-client-rs --connect <host>:9777 --pin <fp> # connect to one
|
||||
```
|
||||
|
||||
## Which should I use?
|
||||
|
||||
| You're streaming to… | Use |
|
||||
|---|---|
|
||||
| A Mac, iPhone, iPad, or Apple TV | The **Apple app** |
|
||||
| Windows, Android, Steam Deck, a browser, a TV | **Moonlight** |
|
||||
| Another Linux box (testing) | **`punktfunk-client-rs`** |
|
||||
| A Linux desktop or laptop, or a Steam Deck | **`punktfunk-client`** (GTK4) |
|
||||
| Windows, Android, a browser, a TV | **Moonlight** |
|
||||
| Automated tests / latency measurement | **`punktfunk-client-rs`** (headless) |
|
||||
|
||||
Whichever you choose, the first connection needs a one-time [pairing](/docs/pairing).
|
||||
|
||||
@@ -43,12 +43,13 @@ The client requests a bitrate; the host encodes to it. To find a good value for
|
||||
|
||||
## Multiple devices at once
|
||||
|
||||
A host can stream to several clients simultaneously — each gets its own virtual display at its own
|
||||
resolution. This is the natural way to put your desktop on a laptop *and* a TV at the same time (both
|
||||
see and control the same desktop).
|
||||
Today the native `punktfunk/1` host (`serve --native`) streams **one session at a time** — additional
|
||||
clients wait in the accept queue until the active session ends. Each session gets its own virtual
|
||||
display at the client's exact resolution; concurrent native sessions are on the roadmap.
|
||||
|
||||
The number of simultaneous streams is bounded by your GPU's encoder. Cap it with
|
||||
`--max-concurrent N` on the host command line (default 4); extra clients wait until a slot frees.
|
||||
(`m3-host`, the standalone test host, has a `--max-concurrent N` knob, default 4, bounded by your
|
||||
GPU's encoder — see the [Host CLI](/docs/host-cli) reference — but `serve --native` does **not** take
|
||||
that flag.)
|
||||
|
||||
## Codec and FEC
|
||||
|
||||
|
||||
@@ -113,9 +113,10 @@ mDNS. It requires **PIN pairing** by default (secure on a LAN); pair once from y
|
||||
## 4. Connect a client
|
||||
|
||||
From any [client](/docs/clients) — `punktfunk-client --discover` finds the host on the LAN. On
|
||||
first connect, complete the PIN pairing (arm it from the host's web console / mgmt API, or run the
|
||||
host with `--allow-pairing`). See [Clients](/docs/clients) and
|
||||
[Running as a Service](/docs/running-as-a-service).
|
||||
first connect, complete the PIN pairing — **arm it from the host's web console / mgmt API**, which
|
||||
makes the host display a 4-digit PIN to type into the client. (Pairing is required by default; pass
|
||||
`serve --native --open` only if you deliberately want to disable the requirement.) See
|
||||
[Clients](/docs/clients) and [Running as a Service](/docs/running-as-a-service).
|
||||
|
||||
## Appendix — build from source
|
||||
|
||||
|
||||
@@ -21,10 +21,18 @@ punktfunk-host serve --native
|
||||
| `--native-port <PORT>` | Native QUIC port (default `9777`). |
|
||||
| `--open` | Don't require pairing — serve any device on the network. Off by default; only for trusted single-user setups. |
|
||||
| `--mgmt-bind <IP:PORT>` | Management API address (default loopback `127.0.0.1:47990`). |
|
||||
| `--mgmt-token <TOKEN>` | Bearer token for the management API; required when `--mgmt-bind` isn't loopback. |
|
||||
| `--mgmt-token <TOKEN>` | Override the bearer token for the management API. |
|
||||
|
||||
By default the host **requires pairing** — see [Pairing & Trust](/docs/pairing). Arm pairing from the
|
||||
web console (or the `m3-host` flags below for a quick test).
|
||||
These are the only flags `serve` accepts.
|
||||
|
||||
The management API is **always HTTPS with bearer-token auth**. If you don't pass `--mgmt-token`, a token
|
||||
is auto-generated and persisted to `~/.config/punktfunk/mgmt-token`; `--mgmt-token` only overrides it. A
|
||||
token is **required** when you bind the API off loopback with `--mgmt-bind`.
|
||||
|
||||
By default the host **requires pairing** — see [Pairing & Trust](/docs/pairing). On `serve --native` you
|
||||
**arm pairing from the web console** (or mgmt API); the host then displays a 4-digit PIN. Pass `--open` to
|
||||
turn off the mandatory-pairing default and serve any device on the network (trusted single-user setups
|
||||
only). The pairing flags below are `m3-host`-only and do **not** apply to `serve`.
|
||||
|
||||
## `m3-host`
|
||||
|
||||
@@ -38,12 +46,17 @@ punktfunk-host m3-host --source virtual
|
||||
| Flag | Meaning |
|
||||
|---|---|
|
||||
| `--port <N>` | QUIC listen port (default `9777`). |
|
||||
| `--source virtual` | Use a real virtual display + NVENC (vs. `synthetic` test frames). |
|
||||
| `--source synthetic` · `virtual` | `virtual` uses a real virtual display + NVENC; `synthetic` emits test frames. |
|
||||
| `--seconds <N>` / `--frames <N>` | Bound each session by wall-clock seconds or frame count. |
|
||||
| `--max-concurrent <N>` | Stream at most N sessions at once (default 4); overflow waits in the queue. |
|
||||
| `--max-sessions <N>` | Exit after N sessions (0 = serve forever). |
|
||||
| `--allow-pairing` | Accept PIN pairing; the host prints a PIN when a client pairs. |
|
||||
| `--require-pairing` | Only serve paired devices (implies `--allow-pairing`). |
|
||||
|
||||
`--max-concurrent`, `--allow-pairing`, and `--require-pairing` are **`m3-host`-only** — `serve` does not
|
||||
accept them. On `serve --native` you arm pairing from the web console instead, and concurrency is not
|
||||
yet capped from the command line.
|
||||
|
||||
Both `serve --native` and `m3-host` advertise the host on the network so clients can discover it. List
|
||||
hosts from another machine with `punktfunk-client-rs --discover`.
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: Install the Host
|
||||
description: Pick your distro and install the punktfunk host from its package registry.
|
||||
---
|
||||
|
||||
The package registries are the real distribution channel. Pick your distro, add the repo, and install
|
||||
with your native package manager. Each row links to the full per-distro guide (add the repo, first-run
|
||||
steps, the web console) — those are the source of truth, so this page doesn't duplicate them.
|
||||
|
||||
## Pick your distro
|
||||
|
||||
| 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) |
|
||||
| **Fedora / Bazzite** | rpm-ostree | `rpm-ostree install punktfunk punktfunk-web` | [Fedora — KDE](/docs/fedora-kde) · [Bazzite](/docs/bazzite) · [packaging/rpm](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/rpm/README.md) |
|
||||
| **Arch / Steam Deck** | PKGBUILD / sysext | `makepkg -si` (Arch) · sysext `.raw` (SteamOS/Deck) | [packaging/arch](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/arch/README.md) |
|
||||
|
||||
Each registry is public — no auth, you just trust the repo's signing key. Adding the repo is a
|
||||
one-time step covered in the linked guide; after that, normal `apt upgrade` / `rpm-ostree upgrade`
|
||||
tracks new builds automatically.
|
||||
|
||||
## What the packages are
|
||||
|
||||
- **`punktfunk-host`** — the streaming host. Install this on your Linux + NVIDIA gaming machine.
|
||||
- **`punktfunk-web`** — the browser management console (pairing + status). Recommended alongside the
|
||||
host; on RPM list it explicitly (`rpm-ostree install punktfunk punktfunk-web`).
|
||||
- **`punktfunk-client`** — the GTK4 desktop client, for streaming *to* a Linux box (also shipped via
|
||||
apt / RPM / Arch / Flatpak). On a Steam Deck, this is the package you want.
|
||||
|
||||
## After installing
|
||||
|
||||
1. Add yourself to the `input` group (virtual gamepads need `/dev/uinput`), then re-login. The exact
|
||||
command differs per distro — see your guide (`usermod -aG input "$USER"`, or `ujust
|
||||
add-user-to-input-group` on Bazzite).
|
||||
2. Start the host inside your desktop session:
|
||||
|
||||
```sh
|
||||
punktfunk-host serve --native
|
||||
```
|
||||
|
||||
3. Enable the web console and read its login password, then open `http://<host-ip>:3000`:
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-web
|
||||
journalctl --user -u punktfunk-web-init | sed -n 's/.*password generated: //p'
|
||||
```
|
||||
|
||||
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).
|
||||
|
||||
## Building from source
|
||||
|
||||
If no package exists for your platform, you can build from source — see the repository README. Source
|
||||
builds are a fallback; the registries are the supported path.
|
||||
@@ -4,6 +4,7 @@
|
||||
"index",
|
||||
"how-it-works",
|
||||
"quickstart",
|
||||
"install",
|
||||
"---Host Setup---",
|
||||
"requirements",
|
||||
"ubuntu-gnome",
|
||||
|
||||
@@ -38,13 +38,13 @@ The PIN ceremony is the other path — useful for the *first* device (before the
|
||||
anything) or when you're at the client and the console isn't handy.
|
||||
|
||||
Pairing has to be **armed** on the host before a client can pair (so a random device can't pair
|
||||
itself). Two ways:
|
||||
itself). On the production host (`serve --native`), this is done from the **web console**: open the
|
||||
host's management console, click to arm pairing, and the host displays a 4-digit PIN along with the
|
||||
list of paired devices. This works on a headless host over the network — there is no command-line flag
|
||||
to arm pairing on `serve`.
|
||||
|
||||
- **Web console** *(recommended)* — open the host's management console, click to arm pairing, and it
|
||||
shows the PIN and the list of paired devices. This is the easiest way and works on a headless host
|
||||
over the network.
|
||||
- **Command line** — start the host with `--allow-pairing` (or `--require-pairing`); it prints a PIN
|
||||
in its log when a client begins pairing.
|
||||
(The standalone headless test host, `m3-host`, takes `--allow-pairing`/`--require-pairing` on its
|
||||
command line instead; the production `serve --native` host arms pairing from the console.)
|
||||
|
||||
Then, on the client:
|
||||
|
||||
@@ -57,8 +57,8 @@ By default, the native host **requires** pairing — only devices that have pair
|
||||
the right setting on a shared network: a device has to complete the PIN ceremony once before it can
|
||||
connect.
|
||||
|
||||
If you're on a fully trusted single-user network and want to skip pairing, the host can be run open —
|
||||
but requiring pairing is strongly recommended.
|
||||
If you're on a fully trusted single-user network and want to skip pairing, start the host with
|
||||
`serve --native --open` — but requiring pairing is strongly recommended.
|
||||
|
||||
## Trust-on-first-use
|
||||
|
||||
|
||||
@@ -37,9 +37,9 @@ On the device you want to stream to:
|
||||
network*. Tap 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 (or with
|
||||
`--allow-pairing` on the command line) — the host displays a 4-digit PIN, you type it into the client,
|
||||
and they trust each other from then on. Full details: [Pairing & Trust](/docs/pairing).
|
||||
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).
|
||||
|
||||
## 4. Stream
|
||||
|
||||
|
||||
@@ -10,8 +10,11 @@ description: Common problems setting up or using a punktfunk host, and how to fi
|
||||
- Host and client must be on the **same network/subnet**. Discovery uses mDNS, which doesn't cross
|
||||
routed subnets or most VPNs-without-multicast. As a fallback, add the host by **IP address** in your
|
||||
client.
|
||||
- A firewall on the host can block it. The native protocol uses UDP port **9777** (plus the data
|
||||
port); GameStream/Moonlight uses its standard ports. Allow them on the host's firewall.
|
||||
- A firewall on the host can block it. The native protocol's control plane uses UDP port **9777**. The
|
||||
per-session **data plane** uses an *ephemeral* UDP port negotiated at connect time (currently
|
||||
random) — for a strict firewall, open a UDP range or move the data port. GameStream/Moonlight uses
|
||||
TCP **47984/47989/48010** + UDP **47998–48010** + ENet UDP **47999**. Allow them on the host's
|
||||
firewall.
|
||||
|
||||
## `nvidia-smi` says it can't communicate with the driver
|
||||
|
||||
@@ -56,8 +59,8 @@ Then log out and back in. On other distros this is `sudo usermod -aG input $USER
|
||||
|
||||
## Pairing is rejected / the client can't connect
|
||||
|
||||
- The host **requires pairing** by default. Arm pairing (web console, or `--allow-pairing`), then
|
||||
enter the PIN on the client. See [Pairing & Trust](/docs/pairing).
|
||||
- The host **requires pairing** by default. Arm pairing from the web console, then enter the PIN on
|
||||
the client. See [Pairing & Trust](/docs/pairing).
|
||||
- If you re-installed the host, its identity changed — re-pair the client.
|
||||
|
||||
## Stutter, drops, or high latency
|
||||
@@ -65,8 +68,9 @@ Then log out and back in. On other distros this is `sudo usermod -aG input $USER
|
||||
- Lower the **bitrate**. On a busy or Wi-Fi link, the requested bitrate may be too high — the Apple
|
||||
app's [speed test](/docs/configuration#bitrate) picks a safe value; with Moonlight, set it manually.
|
||||
- Prefer a **wired** connection or 5 GHz Wi-Fi between host and client.
|
||||
- Streaming to **many devices at once** shares the GPU encoder; cap concurrency with
|
||||
`--max-concurrent`.
|
||||
- Streaming to **many devices at once** shares the GPU encoder. The production host
|
||||
(`serve --native`) handles one native session at a time, with extra clients queued; heavy load is
|
||||
usually bitrate-bound, so lower the bitrate first.
|
||||
|
||||
## Still stuck?
|
||||
|
||||
|
||||
@@ -42,39 +42,35 @@ sudo update-initramfs -u && sudo reboot
|
||||
> `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.
|
||||
|
||||
## 2. Dependencies
|
||||
## 2. Install the host (apt)
|
||||
|
||||
Install the build toolchain and runtime libraries:
|
||||
`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 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
|
||||
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
|
||||
```
|
||||
|
||||
Install Rust if you don't have it:
|
||||
|
||||
```sh
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
```
|
||||
|
||||
## 3. Build
|
||||
|
||||
```sh
|
||||
git clone https://git.unom.io/unom/punktfunk.git && cd punktfunk
|
||||
cargo build --release -p punktfunk-host
|
||||
```
|
||||
|
||||
The host binary is at `target/release/punktfunk-host`.
|
||||
|
||||
## 4. Configure
|
||||
|
||||
The host reads its settings from `~/.config/punktfunk/host.env`. For GNOME:
|
||||
`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`.
|
||||
|
||||
## 3. Configure
|
||||
|
||||
The package ships the systemd **user** unit, the `/dev/uinput` udev rule, the socket-buffer sysctl
|
||||
tuning, and an example config. As the desktop user, grant gamepad access and write the GNOME config:
|
||||
|
||||
```sh
|
||||
sudo usermod -aG input "$USER" # /dev/uinput for virtual gamepads (re-login to apply)
|
||||
mkdir -p ~/.config/punktfunk
|
||||
cat > ~/.config/punktfunk/host.env <<'ENV'
|
||||
WAYLAND_DISPLAY=wayland-0
|
||||
@@ -88,18 +84,30 @@ ENV
|
||||
|
||||
See the [Configuration reference](/docs/configuration) for every option.
|
||||
|
||||
## 5. Run
|
||||
## 4. Run
|
||||
|
||||
From a terminal **inside your GNOME session** (so the host can reach Mutter):
|
||||
Start the host as a user service from **inside your GNOME session** (so it can reach Mutter):
|
||||
|
||||
```sh
|
||||
cargo run --release -p punktfunk-host -- serve --native
|
||||
systemctl --user enable --now punktfunk-host
|
||||
journalctl --user -u punktfunk-host -f # watch it come up + print its fingerprint
|
||||
```
|
||||
|
||||
The host starts listening, prints its fingerprint, and advertises itself on the network. Now
|
||||
[connect a client](/docs/clients).
|
||||
The host listens on UDP `9777` (native punktfunk/1) plus the GameStream ports, and advertises itself
|
||||
over mDNS. It requires **PIN pairing** by default (secure on a LAN) — arm pairing from the web
|
||||
console (next step) and pair once from your [client](/docs/clients).
|
||||
|
||||
To run it automatically at boot — including on a **headless** machine with no monitor — see
|
||||
### Web console
|
||||
|
||||
The console (status, paired devices, arm pairing) ships as `punktfunk-web`:
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-web
|
||||
# read the auto-generated login password, then open http://<host-ip>:3000
|
||||
journalctl --user -u punktfunk-web-init | sed -n 's/.*password generated: //p'
|
||||
```
|
||||
|
||||
To run the host automatically at boot — including on a **headless** machine with no monitor — see
|
||||
[Running as a Service](/docs/running-as-a-service).
|
||||
|
||||
## Troubleshooting
|
||||
@@ -111,3 +119,34 @@ To run it automatically at boot — including on a **headless** machine with no
|
||||
capture. On a headless/always-on host, disable the lock — see
|
||||
[Running as a Service](/docs/running-as-a-service).
|
||||
- More in [Troubleshooting](/docs/troubleshooting).
|
||||
|
||||
## 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`. Write `~/.config/punktfunk/host.env` as in
|
||||
step 3, then run it inside your GNOME session:
|
||||
|
||||
```sh
|
||||
cargo run --release -p punktfunk-host -- serve --native
|
||||
```
|
||||
|
||||
@@ -8,21 +8,42 @@ create a per-client virtual display. Needs **KWin 6.5.6 or newer**.
|
||||
|
||||
> New to this? Skim [Requirements](/docs/requirements) first.
|
||||
|
||||
## NVIDIA driver, dependencies, and build
|
||||
## 1. NVIDIA driver
|
||||
|
||||
These steps are identical to the GNOME guide — follow **steps 1–3** of
|
||||
[Ubuntu — GNOME](/docs/ubuntu-gnome#1-nvidia-driver):
|
||||
Identical to the GNOME guide — follow **step 1** of
|
||||
[Ubuntu — GNOME](/docs/ubuntu-gnome#1-nvidia-driver): install the NVIDIA driver **and** the
|
||||
`libnvidia-gl-<version>` userspace, enable `nvidia-drm modeset=1`, reboot, and verify with
|
||||
`nvidia-smi`.
|
||||
|
||||
1. Install the NVIDIA driver **and** the `libnvidia-gl-<version>` userspace; enable `nvidia-drm
|
||||
modeset=1`; reboot and verify with `nvidia-smi`.
|
||||
2. Install the build toolchain and runtime libraries (the same `apt` line).
|
||||
3. Clone and `cargo build --release -p punktfunk-host`.
|
||||
## 2. Install the host (apt)
|
||||
|
||||
## Configure
|
||||
|
||||
The host reads `~/.config/punktfunk/host.env`. For KDE Plasma:
|
||||
The host is published as a `.deb` to the public Gitea apt registry — install and update with plain
|
||||
`apt`. Trust the repo's signing key, add the repo, and install:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
This also pulls the web console (`punktfunk-web`) via `Recommends` (the pairing/status UI). The
|
||||
desktop *client* — `punktfunk-client`, for the machine you stream *to* — is a separate package, not
|
||||
needed on a host. The NVIDIA driver stays out of band (step 1). Updates later are just
|
||||
`sudo apt update && sudo apt upgrade`.
|
||||
|
||||
## 3. Configure
|
||||
|
||||
The package ships the systemd **user** unit, the udev rule, and the sysctl tuning. As the desktop
|
||||
user, grant gamepad access and write the KDE config:
|
||||
|
||||
```sh
|
||||
sudo usermod -aG input "$USER" # /dev/uinput for virtual gamepads (re-login to apply)
|
||||
mkdir -p ~/.config/punktfunk
|
||||
cat > ~/.config/punktfunk/host.env <<'ENV'
|
||||
WAYLAND_DISPLAY=wayland-0
|
||||
@@ -38,15 +59,26 @@ ENV
|
||||
> virtual-display path is Wayland-only. See the [Configuration reference](/docs/configuration) for
|
||||
> every option.
|
||||
|
||||
## Run
|
||||
## 4. Run
|
||||
|
||||
From a terminal **inside your Plasma session**:
|
||||
Start the host as a user service from **inside your Plasma session**:
|
||||
|
||||
```sh
|
||||
cargo run --release -p punktfunk-host -- serve --native
|
||||
systemctl --user enable --now punktfunk-host
|
||||
journalctl --user -u punktfunk-host -f # watch it come up + print its fingerprint
|
||||
```
|
||||
|
||||
The host starts listening and advertises itself on the network. Now [connect a client](/docs/clients).
|
||||
The host listens on UDP `9777` (native punktfunk/1) plus the GameStream ports and advertises over
|
||||
mDNS. It requires **PIN pairing** by default — arm pairing from the web console and pair once from
|
||||
your [client](/docs/clients).
|
||||
|
||||
### Web console
|
||||
|
||||
```sh
|
||||
systemctl --user enable --now punktfunk-web
|
||||
# read the auto-generated login password, then open http://<host-ip>:3000
|
||||
journalctl --user -u punktfunk-web-init | sed -n 's/.*password generated: //p'
|
||||
```
|
||||
|
||||
To run it at boot — including fully **headless**, with KWin brought up automatically and no login —
|
||||
see [Running as a Service](/docs/running-as-a-service); the headless appliance is built around KDE.
|
||||
@@ -56,3 +88,21 @@ see [Running as a Service](/docs/running-as-a-service); the headless appliance i
|
||||
- **KWin too old:** virtual outputs need KWin **≥ 6.5.6**. Check with `kwin_wayland --version`.
|
||||
- **No picture / capture fails:** confirm you're on a Wayland session and the NVIDIA GL userspace is
|
||||
installed (`libnvidia-gl-<version>`). More in [Troubleshooting](/docs/troubleshooting).
|
||||
|
||||
## Appendix — build from source
|
||||
|
||||
If the apt registry has no build for your release, compile the host yourself (no clean updates / no
|
||||
packaged units). Install the build toolchain and runtime libraries — the same `apt` line as the
|
||||
[GNOME build-from-source appendix](/docs/ubuntu-gnome#appendix--build-from-source) — then:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
Write `~/.config/punktfunk/host.env` as in step 3, then run it inside your Plasma session:
|
||||
|
||||
```sh
|
||||
cargo run --release -p punktfunk-host -- serve --native
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user