Files
punktfunk/docs-site/content/docs/arch.md
T
enricobuehler c2bc72a8e9
apple / swift (push) Successful in 1m11s
android / android (push) Successful in 4m1s
apple / screenshots (push) Successful in 4m29s
arch / build-publish (push) Successful in 5m52s
ci / web (push) Successful in 1m16s
ci / docs-site (push) Successful in 1m11s
ci / rust (push) Successful in 4m54s
deb / build-publish (push) Successful in 3m0s
decky / build-publish (push) Successful in 24s
ci / bench (push) Successful in 4m44s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 32s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 2m50s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 2m30s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 53s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 2m18s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 10m14s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 10m5s
docker / deploy-docs (push) Successful in 22s
fix(packaging): correct CachyOS firewall to ufw + ship ufw openers + web-console opener
CachyOS ships ufw enabled by default (firewalld is not installed) — verified live
on the .21 box — but the docs and shipped firewall openers claimed "CachyOS enables
firewalld by default". Correct that everywhere and ship a ufw application profile
(the one-liner analogue of the firewalld service files):

- packaging/linux/punktfunk.ufw (new): [punktfunk-native], [punktfunk-gamestream],
  [punktfunk-web] profiles, installed to /etc/ufw/applications.d/punktfunk by the
  Arch (CachyOS) and .deb host packages. `sudo ufw allow punktfunk-native`.
- packaging/linux/punktfunk-web.xml (new): firewalld service for the optional web
  console (TCP 47992), installed by the host package on arch/deb/rpm. Neither the
  native nor gamestream opener covered 47992, so a firewalld/ufw host that enabled
  punktfunk-web could not reach the console over the LAN.
- Fix the "CachyOS enables firewalld" claim in arch.md, arch/README.md,
  debian/README.md, both firewalld service .xml comments, and the pacman scriptlet;
  firewalld now attributed to the spins that use it (EndeavourOS, Fedora/RHEL).
- Docs present both one-liners (ufw + firewalld) whichever firewall you run, plus a
  console-opener step; postinst/scriptlet hints detect ufw as well as firewalld.

The native data plane stays hole-punched (ephemeral UDP, no fixed port) — its
openers correctly open only 9777/udp + mDNS; the stale "open a UDP range" note is
replaced with the accurate outbound-UDP explanation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 16:52:35 +00:00

8.0 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 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, enable the service, and enable linger so it starts at boot without a login:

mkdir -p ~/.config/punktfunk
cp /usr/share/punktfunk/host.env.example ~/.config/punktfunk/host.env   # then edit
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 guide — cp /usr/share/punktfunk/host.env.kde ~/.config/punktfunk/host.env and enable it alongside the host). See Configuration for every knob and Running as a Service for the service model.

Check it came up:

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:

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:

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?.

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) stays loopback-only and is never opened. 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 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 and Pairing.

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 SteamOS systemd-sysext path are in packaging/arch/README.md.