Files
punktfunk/docs-site/content/docs/arch.md
T
enricobuehlerandClaude Opus 5 d383161723
ci / rust (push) Failing after 2m31s
ci / docs-site (push) Successful in 1m22s
ci / web (push) Successful in 1m48s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 1m1s
ci / rust-arm64 (push) Successful in 2m2s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 11s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 9s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 9s
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 9s
docker / builders-arm64cross (push) Successful in 20s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Canceled after 36s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Canceled after 36s
docker / deploy-docs (push) Canceled after 0s
docs: the docs catch up with five releases of shipped work
~1150 feat/fix commits landed since v0.19 and the docs drifted badly. This is a
full sweep of every page against the code as shipped: ~280 verified corrections,
nine new pages, and one deletion.

The worst of what was wrong: the quickstart's five-minute path could not work
(`serve` never started the web console, so step 3 had no PIN to read); every
packaged Linux host runs `serve --gamestream` while security.md told readers to
leave GameStream off; HDR was documented as Windows-only; `PUNKTFUNK_SECURE_DDA`
was documented as a working knob that nothing reads; `PUNKTFUNK_INPUT_BACKEND`
listed a `uinput` value that does not exist and named libei for KDE instead of
kwin; README linked three pages deleted on 2026-07-05; and the rpm-ostree update
command pointed at a script no package installs.

Completeness: about half of what shipped since v0.19 had no page at all. New:
support-matrix (what works where, from 217 verified capability cells), input
(mouse/touch/pen — and the in-stream chords, so the docs finally say how to get
your mouse back), client-settings, profiles-and-links, game-library, clipboard,
wake-on-lan, hdr, uninstall. Updating existed but had zero inbound links.

status.md is gone: its facts moved into the support matrix, its shell stays as a
redirect so the public URL does not 404. roadmap.md is themes now, not a feature
checklist — checkboxes are what rotted.

Debian is no longer claimed. The .deb's Depends resolve against Ubuntu images,
nothing in CI builds or tests Debian, and Debian 12 is below the glibc 2.39
floor. The `debian` in the repo URL is the package format.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 17:37:06 +02:00

10 KiB
Raw Blame History

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; on AMD/Intel HEVC and AV1 go through Vulkan Video, with VAAPI for H.264 and as the fallback (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. HEVC/AV1 encode goes through Vulkan Video by default, so install the Vulkan driver — vulkan-radeon (AMD) or vulkan-intel (Intel) — alongside the VAAPI drivers (libva-mesa-driver for AMD, intel-media-driver for Intel), which carry H.264 and the fallback path. Both are 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 -Syu punktfunk-host      # the streaming host
sudo pacman -Syu punktfunk-web       # optional: the browser management console (pairing + status)
sudo pacman -Syu punktfunk-gamescope # optional: HDR (10-bit BT.2020 PQ) off gamescope sessions
sudo pacman -Syu punktfunk-scripting # optional: the plugin/script runner (see below)
sudo usermod -aG input "$USER"       # /dev/uinput access for virtual gamepads (re-login to apply)

Each install is a full -Syu, on purpose: our packages are built against current Arch sonames, and pacman -Sy <pkg> would drop one onto a system whose other packages are still old — the classic partial upgrade that breaks Arch boxes. To take several in one go, name them on a single line: sudo pacman -Syu punktfunk-host punktfunk-web punktfunk-gamescope.

punktfunk-scripting is the runner behind Plugins; it isn't started for you — systemctl --user enable --now punktfunk-scripting when you want it. 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 a normal sudo pacman -Syu, then systemctl --user restart punktfunk-host so the running host picks up the new binary. A -Syu moves every Punktfunk package you installed, so restart punktfunk-web the same way if you run the console. The web console can run the update for you — see Updating the Host; on Arch that button additionally needs PACMAN_FULL_SYSUPGRADE=1 in /etc/punktfunk/update.conf, because the only pacman update we will run is a full one.

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. The unit you enabled in step 4 runs serve --gamestream — the package installs it as it ships and only rewrites the binary path — so that host serves both the native punktfunk/1 plane and stock Moonlight clients, and needs both openers:

# ufw — CachyOS (and Ubuntu, once you enable ufw):
sudo ufw allow punktfunk-native
sudo ufw allow punktfunk-gamestream

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

Switched the host to native-only — dropped --gamestream with a systemctl --user edit punktfunk-host drop-in, or you run punktfunk-host serve by hand? Then open punktfunk-native alone and leave punktfunk-gamestream closed. systemctl --user cat punktfunk-host shows which one yours is.

punktfunk-native opens the QUIC control port (UDP 9777), mDNS discovery and the mgmt/library API (TCP 47990); punktfunk-gamestream opens the fixed Moonlight ports — TCP 47984, 47989 and 48010, UDP 4799848000 — plus the same 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.

Next steps

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 and PF_WITH_SCRIPTING=1 to also build punktfunk-scripting — both need 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.)