Infrastructure-as-Code-Rezept für den Raspberry Pi 4, der als dedizierter Moonlight-Client am Wohnzimmer-TV direkt in den Stream des heimischen Steam-Gaming-Servers (Sunshine) bootet — großes Spiele-Kiosk-Grid, kein Desktop, kein Login, keine Interaktion. Statt SD-Karten-Images zu sichern ist der komplette Zustand ein idempotentes Bash-Skript: frisches Raspberry Pi OS flashen, Skript per SSH reinpipen, nach ~15 Minuten ist der Kiosk vollständig rekonstruiert.
Technisch bewusst minimal: moonlight-qt rendert via SDL2+KMSDRM direkt in den Framebuffer — ohne X, ohne Wayland, ohne Display-Manager; der Autostart ist ein einziger @reboot-Cron-Eintrag. Ein Python-Watchdog hält den Stream in einer Restart-Schleife am Leben und meldet Abstürze strukturiert an die zentrale Bug-Inbox, damit stille Kiosk-Ausfälle sichtbar werden. Vor jedem Stream-Versuch weckt er den Gaming-Server über einen zentralen Wake-on-LAN-Orchestrator — der Host darf so bei Leerlauf schlafen (Scale-to-Zero) und steht beim Einschalten des Kiosks automatisch wieder bereit.
Infrastructure-as-code recipe for a Raspberry Pi 4 that acts as a dedicated Moonlight client at the living room TV, booting straight into the stream of the home Steam gaming server (Sunshine) — a full-screen game kiosk grid, no desktop, no login, no interaction. Instead of backing up SD card images, the entire state is one idempotent bash script: flash a fresh Raspberry Pi OS, pipe the script in over SSH, and the kiosk is fully reconstructed in about 15 minutes.
Deliberately minimal stack: moonlight-qt renders via SDL2+KMSDRM straight to the framebuffer — no X, no Wayland, no display manager; autostart is a single @reboot cron entry. A Python watchdog keeps the stream alive in a restart loop and reports crashes to the central bug inbox, so silent kiosk failures become visible. Before each stream attempt it wakes the gaming server through a central Wake-on-LAN orchestrator — letting the host sleep when idle (scale-to-zero) and come back automatically the moment the kiosk powers on.
Was es tut
Am Wohnzimmer-Fernseher hängt ein Kleinrechner. Strom an — und auf dem Bild steht die Spiele-Auswahl. Kein Desktop, keine Anmeldung, kein Mauszeiger. Gespielt wird nicht auf diesem Gerät, sondern auf dem Rechner im Keller; hierher kommt nur das fertige Bild.
Für die Kinder ist das ein Fernseher mit Spielen drauf. Genau so soll es sein.
Der Zustand ist ein Skript, kein Abbild
Der übliche Weg wäre, die Speicherkarte einmal einzurichten und danach ein Abbild davon wegzusichern. Das ist bequem — bis die Karte nach zwei Jahren stirbt, das Abbild veraltet ist und niemand mehr weiß, was seither von Hand nachgestellt wurde.
Hier ist der komplette Zustand ein einziges Skript, das man beliebig oft laufen lassen kann. Frisches System aufspielen, Skript hineinschieben, eine Viertelstunde warten — der Kiosk ist wieder da, mitsamt allem, was jemals daran eingestellt wurde. Wer etwas ändert, ändert das Skript, nicht das Gerät.
Weniger ist hier wirklich weniger
Kein Fenstersystem, keine Anmeldeoberfläche, kein Desktop. Das Bild geht direkt an die Grafik, gestartet wird es von einem einzigen Eintrag beim Hochfahren. Das spart nicht nur Rechenzeit auf einem kleinen Gerät — es entfernt vor allem die Hälfte der Dinge, die kaputtgehen können.
Der Wächter — der eigentliche Grund, warum es zuverlässig ist
Ein Gerät am Fernseher hat eine unangenehme Eigenschaft: Wenn es nicht geht, sagt es niemand. Man schaltet ein, es kommt kein Bild, man macht etwas anderes. Wochen später fällt auf, dass es seit einem Update nicht mehr läuft.
Deshalb sitzt ein kleiner Wächter davor. Er macht drei Dinge:
- Wecken. Der Spiele-Rechner darf schlafen; vor jedem Versuch wird er geweckt und es wird
gewartet, bis er wirklich da ist.
- Am Leben halten. Bricht der Stream ab, wird neu verbunden statt schwarz zu bleiben.
- Melden. Jeder Absturz geht in dieselbe zentrale Ablage wie die Fehler aller anderen
Projekte. Ein stiller Ausfall im Wohnzimmer ist damit nicht mehr still.
Das dritte ist das wichtigste — und die Lehre, die in mehreren meiner Projekte wieder auftaucht: Ein System, das nichts sagt, ist nicht dasselbe wie ein System, dem es gut geht.
What it does
A small computer sits at the living room TV. Power on — and the game selection is on screen. No desktop, no login, no mouse pointer. The games do not run on this device but on the machine in the basement; only the finished picture arrives here.
To the kids it is a TV with games on it. That is exactly the point.
The state is a script, not an image
The usual approach is to set the memory card up once and then back up an image of it. That is convenient — until the card dies after two years, the image is out of date and nobody remembers what was adjusted by hand since.
Here the entire state is a single script that can be run any number of times. Flash a fresh system, pipe the script in, wait a quarter of an hour — the kiosk is back, including everything ever configured on it. Whoever changes something changes the script, not the device.
Less really is less here
No window system, no login screen, no desktop. The picture goes straight to the graphics hardware, started by a single entry at boot. That does not only save compute on a small device — above all it removes half of the things that can break.
The watchdog — the actual reason it is reliable
A device at the TV has an unpleasant property: when it doesn't work, nobody says so. You switch it on, no picture appears, you do something else. Weeks later somebody notices it has been dead since an update.
So a small watchdog sits in front of it. It does three things:
- Wake. The gaming machine is allowed to sleep; before each attempt it is woken and the
watchdog waits until it is really there.
- Keep alive. If the stream drops, it reconnects instead of staying black.
- Report. Every crash goes into the same central place as the errors of all my other
projects. A silent failure in the living room is no longer silent.
The third is the most important — and the lesson that keeps reappearing across my projects: a system that says nothing is not the same as a system that is fine.