Files
punktfunk/packaging/debian
enricobuehler 6922e1c467
apple / swift (push) Successful in 55s
ci / rust (push) Failing after 1m35s
ci / web (push) Successful in 28s
windows-host / package (push) Successful in 2m23s
ci / docs-site (push) Successful in 30s
android / android (push) Successful in 3m24s
deb / build-publish (push) Successful in 3m22s
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 4s
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
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 4s
ci / bench (push) Successful in 4m48s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m50s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 8m51s
docker / deploy-docs (push) Successful in 18s
feat(host): VAAPI codec probe + AMD/Intel packaging + neutral logs (Phase 3)
Polish for AMD/Intel support:
- GameStream serverinfo advertises only codecs the GPU can ACTUALLY encode on
  the VAAPI backend (probed once by opening a tiny encoder per codec). AV1
  encode is narrow (Intel Arc/Xe2+, AMD RDNA3+/RDNA4) and an old iGPU may lack
  HEVC, so a Moonlight client never negotiates a codec the encoder can't open.
  NVENC/Windows keep the Moonlight-validated static mask. Validated on a Radeon
  780M: h264/h265/av1 all probe true -> mask unchanged (65793).
- Packaging: Recommends mesa-va-drivers + intel-media-va-driver (deb) /
  mesa-va-drivers + intel-media-driver (rpm) so the auto-selected VAAPI backend
  works out of the box on AMD/Intel; NVIDIA boxes can --no-install-recommends.
  (Fedora note: stock mesa-va-drivers disables HEVC/AV1 -- needs the freeworld
  variant from RPM Fusion.)
- De-NVIDIA-fy the user-facing encoder log/context strings ("open NVENC" ->
  "open video encoder") now that VAAPI is a first-class backend.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:41:37 +00:00
..

punktfunk-host — Debian/Ubuntu package (apt)

punktfunk-host is published as a .deb to Gitea's Debian package registry in the public unom org, so the Ubuntu hosts update with plain apt. CI (.gitea/workflows/deb.yml) builds and publishes on every push to main (a rolling 0.2.0~ciN.g<sha> build) and on host-v* tags (a clean X.Y.Z) — the rolling builds outrank the stray 0.1.1, so plain apt upgrade always gets the latest (no version pin needed).

The same workflow also publishes punktfunk-web (the browser management console — pairing + status) and punktfunk-client (the GTK4 couch/Deck client). punktfunk-host Recommends punktfunk-web, so a default apt install punktfunk-host pulls the console too (alongside the udev/sysctl bits) unless you've disabled weak deps; punktfunk-client is independent — install it on the box you stream to. (punktfunk-probe is the headless reference/test tool, not packaged here.)

Package layout mirrors the Fedora RPM (../rpm/punktfunk.spec): the host binary, the /dev/uinput udev rule, the systemd user unit, headless session helpers, the example config, and the OpenAPI doc. Runtime Depends are computed by dpkg-shlibdeps from the binary itself (built in the Ubuntu 26.04 rust-ci image, so the lib soname package names match the target). The NVIDIA driver (libnvidia-encode / libEGL_nvidia / libcuda) is not a dependency — it's installed out of band, like on the RPM side.

Install on a host (one-time)

The registry is public, so no apt auth is needed — just trust the repo's signing key:

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

Then, as the desktop user:

sudo usermod -aG input "$USER"          # virtual gamepads (re-login to take effect)
mkdir -p ~/.config/punktfunk
cp /usr/share/punktfunk-host/host.env.example ~/.config/punktfunk/host.env   # then edit
systemctl --user enable --now punktfunk-host
# Web console — 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'

Firewall

Open the ports the host listens on. The native punktfunk/1 plane:

  • QUIC control plane: UDP 9777 (serve --native --native-port N to change).
  • Data plane: an ephemeral UDP port — negotiated per session, so there is no fixed port to open. For a restrictive firewall you'd need to allow a UDP range (the repo does not pin one).

And the GameStream / Moonlight ports (fixed):

Port Proto Purpose
47984 TCP HTTPS nvhttp (paired, mutual-TLS)
47989 TCP HTTP nvhttp (/serverinfo, /pair PIN flow)
48010 TCP RTSP handshake
4799848010 UDP Video RTP (+ FEC), ENet control (47999), audio (48000)
5353 UDP mDNS auto-discovery

The mgmt API (TCP 47990) binds to loopback by default — leave it closed unless you move it off loopback with --mgmt-bind IP:PORT (which then requires --mgmt-token).

With ufw:

sudo ufw allow 9777/udp                                 # punktfunk/1 control plane
sudo ufw allow 47984/tcp && sudo ufw allow 47989/tcp && sudo ufw allow 48010/tcp
sudo ufw allow 47998:48010/udp
sudo ufw allow 5353/udp
# plus the ephemeral punktfunk/1 data port — open a UDP range you reserve for it.

With raw nftables (add to your inet filter input chain):

udp dport 9777 accept                  # punktfunk/1 control plane
tcp dport { 47984, 47989, 48010 } accept
udp dport { 47998-48010, 5353 } accept
# plus the ephemeral punktfunk/1 data port (a reserved UDP range).

Updates

sudo apt update && sudo apt upgrade        # picks up the newest published build
systemctl --user restart punktfunk-host    # if the unit was already running

Build a .deb locally

VERSION=0.0.1 bash packaging/debian/build-deb.sh   # -> dist/punktfunk-host_0.0.1_amd64.deb

Needs dpkg-dev (dpkg-shlibdeps, dpkg-deb). It builds the release binary first if missing. Build it in the rust-ci image (or on an Ubuntu 26.04 box) so the resolved Depends match the hosts; building on a GPU box is fine — the NVIDIA driver lib is filtered out either way.