e586961e0b
ci / rust (push) Has been cancelled
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>
63 lines
2.6 KiB
Markdown
63 lines
2.6 KiB
Markdown
---
|
|
title: "Headless KDE Box Setup"
|
|
description: "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 `--virtual` gained `createVirtualOutput`), or a DRM backend. On a box
|
|
with no KMS scanout, `kwin --drm` is impossible — use the headless/virtual path below.
|
|
- NVIDIA driver with GL/EGL userspace (see [Linux Host Setup](/docs/linux-setup) for the build deps).
|
|
|
|
## Bring up the session
|
|
|
|
The headless Plasma session is launched by [`scripts/headless/run-headless-kde.sh`](https://github.com),
|
|
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:
|
|
|
|
```sh
|
|
# 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:
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
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](/docs/gnome-box)) or Sway/wlroots. Each compositor keeps its own
|
|
`VirtualDisplay` backend — there's no cross-compositor protocol for client-sized outputs.
|