Per the new docs workflow (docs-site = KB layer; repo docs/ keeps design notes): - Add a canonical Status & Progress tracker (status.md): milestones, per-box live state, and a dated progress log — the go-forward place to track progress. - Add setup guides: GNOME/Mutter host (gnome-box — Secure Boot MOK enroll, the libnvidia-gl EGL fix, autologin, screen-lock disable, appliance unit), headless KDE box, and Bazzite host (ujust input group, gamescope session, gotchas). - Roadmap is now canonical in docs-site (synced the skew-handshake section 12 update); removed the repo docs/roadmap.md copy and repointed README to docs-site. - Nav (meta.json) + landing cards updated; site builds (bun run build). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.6 KiB
title, description
| title | description |
|---|---|
| Headless KDE Box Setup | Run punktfunk on a headless box with a nested KWin/Plasma session — the boot-appliance pattern. |
How to run a punktfunk host on a headless box (no physical display / KMS scanout) using the
KWin backend: a nested headless Plasma session on WAYLAND_DISPLAY=wayland-kde, captured into a
per-client virtual output. This is the dev-box pattern (a QEMU VM with a passthrough NVIDIA GPU, no
KMS scanout → everything renders offscreen via renderD128).
Requirements
- KWin ≥ 6.5.6 (headless
--virtualgainedcreateVirtualOutput), or a DRM backend. On a box with no KMS scanout,kwin --drmis impossible — use the headless/virtual path below. - NVIDIA driver with GL/EGL userspace (see Linux Host Setup for the build deps).
Bring up the session
The headless Plasma session is launched by scripts/headless/run-headless-kde.sh,
which starts kwin --virtual on wayland-kde plus the full Plasma desktop (portals, polkit agent, a
supervised plasmashell). It sets the env Plasma needs — notably XDG_MENU_PREFIX=plasma-, without
which plasmashell runs but the launcher menu is empty:
# shell 1 — the compositor session
bash scripts/headless/run-headless-kde.sh 1920x1080
# shell 2 — the host
WAYLAND_DISPLAY=wayland-kde XDG_CURRENT_DESKTOP=KDE PUNKTFUNK_VIDEO_SOURCE=virtual \
PUNKTFUNK_ZEROCOPY=1 cargo run -rp punktfunk-host -- serve --native
Boot appliance (no login, comes up at boot)
Two user systemd units bring the whole thing up at boot with no interaction:
cp scripts/punktfunk-kde-session.service scripts/punktfunk-host.service ~/.config/systemd/user/
cp scripts/host.env.example ~/.config/punktfunk/host.env # edit for the kwin backend
systemctl --user daemon-reload
systemctl --user enable punktfunk-kde-session punktfunk-host
sudo loginctl enable-linger "$USER" # start user units at boot WITHOUT a login
reboot
punktfunk-kde-session.service runs the headless KWin/Plasma session; punktfunk-host.service
(serve --native) After=s it and starts listening immediately (it only touches the compositor
per session, so the ordering is soft). host.env for this backend:
WAYLAND_DISPLAY=wayland-kde
XDG_CURRENT_DESKTOP=KDE
PUNKTFUNK_COMPOSITOR=kwin
PUNKTFUNK_VIDEO_SOURCE=virtual
PUNKTFUNK_ZEROCOPY=1
Other backends
The same box can stream a nested app (no desktop) via the gamescope backend, or attach to GNOME
(GNOME Box Setup) or Sway/wlroots. Each compositor keeps its own
VirtualDisplay backend — there's no cross-compositor protocol for client-sized outputs.