Files
punktfunk/docs-site/content/docs/arch.md
T
enricobuehlerandClaude Fable 5 19392918ff
ci / web (push) Successful in 1m9s
ci / docs-site (push) Successful in 1m14s
ci / rust-arm64 (push) Successful in 3m28s
deb / build-publish-client-arm64 (push) Successful in 2m28s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 10s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 9s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 11s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 8s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 9s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 12s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 29s
android / android (push) Successful in 5m47s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m16s
docker / builders-arm64cross (push) Successful in 9s
deb / build-publish (push) Successful in 6m5s
docker / deploy-docs (push) Successful in 35s
deb / build-publish-host (push) Successful in 6m35s
ci / rust (push) Successful in 6m38s
arch / build-publish (push) Successful in 9m13s
apple / swift (push) Failing after 13m37s
apple / screenshots (push) Skipped
windows-host / package (push) Successful in 17m4s
windows-host / winget-source (push) Skipped
windows-host / canary-manifest (push) Successful in 20s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 16m17s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Canceled after 39s
feat(gamescope/hdr): HDR is attempted by default and every install path ships the patched gamescope
Field report (RX 5700 / SteamOS): 10-bit HEVC "unsupported" — but the GPU was
never the blocker (RADV probed Main10 fine on that box). The session stayed SDR
because stock gamescope offers no 10-bit PQ capture formats and nothing shipped
our pipewire-hdr build outside the Bazzite sysext, while PUNKTFUNK_GAMESCOPE_HDR
additionally defaulted off everywhere. Close all three gaps:

- PUNKTFUNK_GAMESCOPE_HDR now defaults ON (explicit-off grammar, the flip the
  config comment planned post-canary). Safe by construction: the +pfhdr banner
  probe, managed-spawn term, and client 10-bit cap keep stock-gamescope boxes on
  the exact 8-bit path. The nix module's gamescopeHdr (default true now) only
  controls whether the patched binary is on PATH; it no longer sets the env.
- SteamOS: new scripts/steamdeck/build-gamescope.sh builds the HDR gamescope in
  the same pf2 trixie distrobox (apt dep list validated by a full build in a
  debian:trixie container), installs ~/.local/bin/punktfunk-gamescope, and
  maintains PUNKTFUNK_GAMESCOPE_BIN in host.env ONLY while the binary passes its
  on-glass --version/+pfhdr check — a stale absolute override would break
  session spawning, not just HDR. Wired into install.sh (§3b), update.sh
  (retrofit), and rebuild-check.sh (ldd-probes it like the host binary).
- Arch: build-sysext.sh gains a --gamescope fold-in (banner-verified by
  execution, host-image-only), and punktfunk-host optdepends the companion.
  Deliberately NO CI-published host sysext: per the 2026-07-22 packaging
  verdict a prebuilt SteamOS host breaks on A/B soname bumps (and /var is
  per-partition-set), so arch.yml records that instead — SteamOS hosts use the
  distrobox flow above.

Also fixes a latent bug that made build-sysext.sh fail every invocation as
documented: a literal `}` inside `${1:?usage …{host,client}…}` terminates the
expansion early and corrupts $PKG (caught by the new synthetic-package test,
which also covers the fold-in, the unmarked-gamescope refusal, and the
client-image guard).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 13:50:31 +02:00

7.8 KiB

title, description
title description
Arch Linux Install a punktfunk host on Arch (and Arch-derived distros) from the signed pacman binary repo.

Set up a punktfunk host on Arch Linux (or an Arch-derived distro like CachyOS/EndeavourOS). The host installs from a signed pacman binary repo, so it updates with pacman -Syu like the rest of your system — no building required. Host encode is NVENC on NVIDIA and VAAPI on AMD/Intel (PUNKTFUNK_ENCODER=auto picks per GPU).

New here? Read Security & Safe Use first — a streaming host is remote control of the machine, so keep it on a trusted LAN or VPN and require pairing.

Prefer to build it yourself? A split PKGBUILD (host + client + optional web console) is in the repo at packaging/arch/ — see the appendix. The binary repo below is the supported path.

1. GPU prerequisites

  • NVIDIA: sudo pacman -S --needed nvidia-utils (provides NVENC + the EGL/CUDA zero-copy path). Arch's stock ffmpeg already has NVENC built in — no RPM-Fusion-style swap like Fedora needs.
  • AMD / Intel: the Mesa stack (mesa, libva-mesa-driver for AMD, intel-media-driver for Intel) provides the VAAPI encoder — usually already installed on a desktop.

2. Add the signed repo

The registry signs its database and every package, so first trust its key once (after this, packages install signature-verified):

# Trust the registry signing key.
curl -fsS https://git.unom.io/api/packages/unom/arch/repository.key \
  | sudo pacman-key --add -
sudo pacman-key --lsign-key E0CA04465C99C936E0B0C6510A317015A34DDD69

# Add the repo (append to /etc/pacman.conf). No SigLevel line needed — pacman's default
# verifies signed packages against the key you just trusted. (printf, not a heredoc, so this
# works in fish too — CachyOS's default shell has no `<<EOF` support.)
printf '\n[punktfunk]\nServer = https://git.unom.io/api/packages/unom/arch/$repo/$arch\n' \
  | sudo tee -a /etc/pacman.conf >/dev/null

Stable vs canary. [punktfunk] is the stable channel — it moves only when a vX.Y.Z release is cut. For the latest main build, use [punktfunk-canary] instead (same Server line, just the repo name). Enable exactly one. See Release Channels.

3. Install the host

sudo pacman -Sy punktfunk-host      # the streaming host
sudo pacman -S  punktfunk-web       # optional: the browser management console (pairing + status)
sudo pacman -S  punktfunk-gamescope # optional: HDR (10-bit BT.2020 PQ) off gamescope sessions
sudo usermod -aG input "$USER"      # /dev/uinput access for virtual gamepads (re-login to apply)

punktfunk-client (the native GTK4 Linux client) is in the same repo if this box is also a client. The host package ships the systemd user units, the udev rule, the UDP socket-buffer sysctl 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:

mkdir -p ~/.config/punktfunk
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:

Then enable the service and turn on linger so it starts at boot without a login:

systemctl --user daemon-reload
systemctl --user enable --now punktfunk-host
sudo loginctl enable-linger "$USER"

Check it came up:

systemctl --user status punktfunk-host          # active
journalctl --user -u punktfunk-host -f          # watch a client connect

Enable the browser console, find your login password, and arm PIN pairing from The Web Console. For a headless KWin appliance that streams at boot with no graphical login, see KDE → Headless session. Full reference: Configuration · Running as a Service.

5. Open the firewall (if you have one)

Stock Arch ships no firewall — every port is already open, so you can skip this. But CachyOS enables ufw by default (firewalld is not installed), and some other spins (e.g. EndeavourOS) enable firewalld — an Arch package never opens ports for you, so on those the host is unreachable until you allow it.

The punktfunk-host package installs openers for both, so it's a one-liner whichever you run:

# ufw — CachyOS (and Ubuntu, once you enable ufw):
sudo ufw allow punktfunk-native        # the secure native host (the default)
sudo ufw allow punktfunk-gamestream    # …also this if you run `serve --gamestream` (Moonlight)

# firewalld — Fedora-like spins (EndeavourOS, …):
sudo firewall-cmd --reload                                    # load the installed definition
sudo firewall-cmd --permanent --add-service=punktfunk-native
sudo firewall-cmd --reload

punktfunk-native opens the QUIC control port (UDP 9777) + mDNS discovery; add punktfunk-gamestream as well if you run serve --gamestream (the fixed Moonlight ports + mDNS). The media data plane uses an ephemeral UDP port that the client opens with a hole-punch — the host streams back out through the path the client opened, so there's nothing fixed to open as long as the firewall allows outbound UDP (the default for both ufw and firewalld).

Enabled the web console (punktfunk-web, above) and want to reach it from your phone or another machine? It's not opened by the streaming rules — open its port too, the same one-liner way:

sudo ufw allow punktfunk-web                                                            # ufw
sudo firewall-cmd --permanent --add-service=punktfunk-web && sudo firewall-cmd --reload  # firewalld

That opens TCP 47992 (HTTPS, login-gated). The mgmt API (47990) is opened for paired clients by the punktfunk-native profile (game-library browsing over mTLS); off-loopback it serves only read-only status/library, and every admin action stays loopback-only. Full port lists (nftables, explicit ports) are in packaging/arch/README.md.

6. Connect a client

From any client, --discover finds the host on the LAN. On first connect, complete the PIN pairing: arm it from The 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 for per-platform setup.

Appendix — build from source (PKGBUILD)

To build instead of using the binary repo, use the split PKGBUILD in packaging/arch/ (produces punktfunk-host + punktfunk-client; set PF_WITH_WEB=1 to also build punktfunk-web, which needs bun):

git clone https://git.unom.io/unom/punktfunk.git && cd punktfunk/packaging/arch
# Build the working tree (no git fetch):
PF_SRCDIR="$(git rev-parse --show-toplevel)" makepkg -f --holdver
sudo pacman -U punktfunk-host-*.pkg.tar.zst

NVENC/EGL come from the NVIDIA driver (nvidia-utils); on a GPU-less builder, symlink the CUDA stub into the link path first (the PKGBUILD header documents this). Full details, the Fedora→Arch dependency map, and the systemd-sysext mechanism are in packaging/arch/README.md. (For a SteamOS host, use the on-device installer instead — it builds the host and the HDR gamescope against the running OS.)