Files
punktfunk/docs-site/content/docs/running-as-a-service.md
T
enricobuehler 0eedfb3c1f
apple / swift (push) Failing after 0s
apple / screenshots (push) Has been skipped
windows-drivers-provision / provision (push) Successful in 13s
windows-drivers / probe-and-proto (push) Successful in 17s
windows-drivers / driver-build (push) Successful in 1m10s
android / android (push) Successful in 3m19s
ci / web (push) Successful in 39s
ci / docs-site (push) Successful in 53s
windows-host / package (push) Successful in 6m6s
ci / rust (push) Successful in 11m12s
decky / build-publish (push) Successful in 11s
ci / bench (push) Successful in 5m9s
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 21s
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 43s
deb / build-publish (push) Successful in 7m31s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 9m14s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 9m12s
release / apple (push) Failing after 1s
docker / deploy-docs (push) Successful in 19s
flatpak / build-publish (push) Successful in 4m43s
docs: first-class Linux + Windows positioning + IDD-push differentiator
Drop the "Linux-first" framing across the README and docs site in favor of
first-class Linux AND Windows hosts, and surface the Windows IDD-push
virtual-display path as a distinct differentiator (punktfunk's own indirect
display driver the host pushes frames into — a real virtual display, no physical
monitor or dummy plug, even on the secure desktop).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:53:02 +00:00

4.6 KiB

title, description
title description
Running as a Service Start the host at boot — for a desktop you log into, or a fully headless always-on machine.

Running serve in a terminal is fine for trying punktfunk out. To make a machine an always-available host, run it as a service. There are two cases.

The bundled unit scripts/punktfunk-host.service runs serve --gamestream, so it serves both the native punktfunk/1 plane and stock Moonlight clients. For a secure native-only host (no GameStream — its pairing runs over plain HTTP and its legacy encryption is weaker; security-review #5/#9), drop --gamestream from the unit's ExecStart and use bare serve.

A. A desktop you log into

If you sit at the machine (or it auto-logs-in to a desktop), run the host as a systemd user service that starts with your session:

mkdir -p ~/.config/systemd/user
cp scripts/punktfunk-host.service ~/.config/systemd/user/
# Put your host.env in place first — see the setup guide for your desktop.
systemctl --user daemon-reload
systemctl --user enable --now punktfunk-host

The host now starts whenever you log in. Check it with systemctl --user status punktfunk-host.

B. A headless, always-on host

To run with no monitor and no login — a machine in a closet that's always ready — you need two things: a desktop session that comes up at boot, and the host service started without a login.

Start by making the host service start at boot even when nobody logs in:

sudo loginctl enable-linger "$USER"

Then bring up a session automatically, depending on your desktop:

Headless GNOME

Have GDM auto-login your user, so a GNOME Wayland session is always running:

# /etc/gdm3/custom.conf  (Ubuntu)   ·   /etc/gdm/custom.conf  (Fedora)
[daemon]
AutomaticLoginEnable = true
AutomaticLogin = your-user

Then disable the screen lock — a locked GNOME session blocks screen capture, and there's no one to unlock a headless box:

gsettings set org.gnome.desktop.screensaver lock-enabled false
gsettings set org.gnome.desktop.session idle-delay 0

Enable the host user service (section A) and reboot. The host comes up on the auto-login session.

Headless KDE

punktfunk ships a unit that brings up a headless KWin/Plasma session with no display manager, so the host has a desktop to stream even with no monitor attached:

cp scripts/punktfunk-kde-session.service scripts/punktfunk-host.service ~/.config/systemd/user/
# host.env: PUNKTFUNK_COMPOSITOR=kwin, WAYLAND_DISPLAY=wayland-kde
systemctl --user daemon-reload
systemctl --user enable punktfunk-kde-session punktfunk-host
sudo loginctl enable-linger "$USER"
reboot

The session unit starts headless KWin; the host unit follows it and starts listening. (KWin only needs to be up by the time a client connects, so the ordering is soft.)

Headless Bazzite

On Bazzite, the host launches its own gamescope/Steam session per client, so you don't need a separate session unit — see Bazzite.

Windows

punktfunk has first-class Linux and Windows hosts. On Windows it ships as a signed installer with an SCM service and a virtual-display driver — including punktfunk's own indirect display driver the host pushes frames straight into. The Windows host is newer than the Linux host. (Not to be confused with the Windows client, which streams to a Windows PC.)

On Windows the host runs as a LocalSystem service that launches into the interactive session, so it captures the secure desktop (UAC / lock screen) and survives reboots with nobody logged in — the same model Sunshine/Apollo use.

The easy path is the signed installer: download punktfunk-host-setup-<ver>.exe from the package registry (punktfunk-host-windows) and run it. It drops the host into C:\Program Files\punktfunk, optionally installs the bundled SudoVDA virtual-display driver, and registers + starts the service for you (/VERYSILENT for unattended). Upgrades and uninstall are handled through Add/Remove Programs.

Prefer the CLI? Run punktfunk-host service install from an elevated prompt — see Windows service. Either way you need an NVIDIA GPU + driver (the host is NVENC-only on Windows).

Verifying

After a reboot, from another machine on the network:

punktfunk-probe --discover     # or just look for the host in a native client / Moonlight

If the host is listed, it's up. If not, check journalctl --user -u punktfunk-host on the host.