NFC-basierte Zeiterfassung auf Raspberry Pi
Langzeitaufgabe im Rahmen meines Praktikums: ein eigenständiges Terminal zur Arbeitszeiterfassung per NFC, aufgebaut auf einem Raspberry Pi mit 7-Zoll-Touchdisplay und NFC-Leser. Diese Seite dokumentiert die einzelnen technischen Bausteine und ihre Umsetzung.
Praktikumsbetrieb: terraconnect.de ↗Das Gehäuse
Das Wandgehäuse habe ich selbst in CadQuery parametrisch konstruiert und als STEP-Modell exportiert. Es integriert Display, Raspberry Pi und NFC-Leser passgenau und wurde über mehrere Prototyp-Iterationen verfeinert – inklusive USB-C-Aussparung, NFC-Bereich und Wandhalterungen.
Das Modell lässt sich direkt im Browser drehen und zoomen.
Zwei gedruckte Gehäuse-Varianten – und das fertig montierte Terminal mit laufender Zeiterfassung.


01 Betriebssystem
Als Basis dient Raspberry Pi OS Lite – die Variante ohne vorinstallierte grafische Oberfläche. Dadurch startet das System schneller, verbraucht weniger Ressourcen und enthält keine unnötigen Komponenten.
Die grafische Ausgabe übernimmt labwc, ein schlanker Wayland-Compositor. labwc fährt beim Systemstart automatisch hoch und zeigt direkt die Anwendung, ohne Desktop-Umgebung dazwischen.
02 NFC-Leser einbinden
Verwendet wird ein PN532-NFC-Leser, angesprochen über libnfc, das die Kommunikation mit der Hardware übernimmt und die UID der aufgelegten Chips ausliest.
Damit das Frontend die gelesene UID in Echtzeit erhält, läuft eine selbst geschriebene Python-WebSocket-Bridge als Hintergrunddienst. Sie sendet jedes NFC-Ereignis per WebSocket ans Frontend – ständiges Abfragen (Polling) entfällt.
03 Anwendung im Kiosk-Modus
Die Zeiterfassung läuft als Weboberfläche in Chromium im Kiosk-Modus: Vollbild, keine Adressleiste, keine Bedienelemente.
Statt einer festen Wartezeit (sleep) prüft eine Readiness-Schleife, ob der Webdienst schon antwortet, und startet Chromium erst dann – schneller und zuverlässiger als ein starres Warten.
04 Webdienst auf Port 80
Der Webdienst soll auf Port 80 laufen, damit die Adresse ohne Portangabe funktioniert. Ports unter 1024 erfordern unter Linux normalerweise Root-Rechte.
Statt den Dienst als Root zu betreiben, wird dem Node.js-Binary per setcap die Capability cap_net_bind_service zugewiesen. So belegt genau dieser Prozess Port 80, ohne dass der Dienst Administratorrechte bekommt.
05 Display zeitgesteuert abschalten
Über crontab wird das Display außerhalb der Betriebszeiten abgeschaltet und rechtzeitig wieder eingeschaltet. Die Ein-/Aus-Befehle sind als Cronjobs zu festen Uhrzeiten hinterlegt – das spart Strom und schont das Panel, ohne manuelles Eingreifen.
06 Gehäuse
Das Gehäuse wurde selbst konstruiert und 3D-gedruckt (siehe Modell und Fotos oben). Es ist für die Wandmontage ausgelegt und integriert Display, Raspberry Pi und NFC-Leser passgenau. Aussparungen und Befestigungspunkte wurden über mehrere Prototyp-Iterationen angepasst.
Eigenes Homelab
Ein selbst geplantes, gebautes und betriebenes Homelab – gewachsen vom Einzelrechner zu einem Drei-Node-Proxmox-Cluster. Testumgebung und produktive Dienste laufen nebeneinander, mit Fokus auf Systemintegration, Virtualisierung, Netzwerk, Ausfallsicherheit und Self-Hosting.
Der Aufbau
Kompakt im Rack: die drei Cluster-Nodes, das NAS und der Router. Im Hintergrund läuft Proxmox VE mit 17 Containern und VMs, daneben das TrueNAS-Dashboard – und zwei selbst gebaute Live-Dashboards, die Auslastung und Dienste direkt aus der Proxmox-API ziehen.
- 2 Nodes: ein HP Thin Client (AMD GX-420GI, 8 GB) + ein ProDesk
- eine Handvoll Dienste, ein statisches Dashboard
- kein Monitoring, keine DNS-Redundanz
- Backups manuell
- 3 HP-Kleinrechner (Ryzen 3 PRO 2200GE) im Cluster – mit Quorum als Grundlage für Hochverfügbarkeit
- 17 Container/VMs + TrueNAS-Apps
- Monitoring, zweiter DNS-Server & tägliche Backups
- zwei Live-Dashboards und ein KI-Assistent im Cluster
01 Hardware
Angefangen hat alles mit zwei Nodes – einem sparsamen HP Thin Client (AMD GX-420GI) und einem ProDesk. Heute läuft das Lab auf drei HP-Kleinrechnern der G4-Reihe – zwei ProDesk 405 und einem EliteDesk 705 – mit jeweils einem AMD Ryzen 3 PRO 2200GE (4 Kerne) im Proxmox-Cluster. Alle drei Nodes sind inzwischen mit 16 GB RAM bestückt — einer mit einem einzelnen Riegel, die beiden anderen mit je zwei zu 8 GB. Anfangs trug nur ein Node die volle Bestückung als „Compute"-Knoten für VMs, während die beiden anderen mit 4 GB schlanke LXC bedienten.
Gleiche Prozessorgeneration auf allen dreien hält den Betrieb einfach: gleiche Treiber, vergleichbares Verhalten, und drei Nodes ergeben ein stabiles Cluster-Quorum. Der Speicher steht bewusst daneben statt im Cluster: ein eigener Rechner derselben Baureihe, aber mit Intel i5-8500T und sechs Kernen, auf dem TrueNAS läuft.
Dort liegen die Daten in drei getrennten Bereichen, und die Aufteilung folgt der Frage, wie schlimm ein Plattenausfall jeweils wäre. Was nicht wiederzubeschaffen ist – Dokumente, Kalender, die Cloud-Ablage – liegt auf zwei 4-TB-Platten, die sich gegenseitig spiegeln: fällt eine aus, läuft der Betrieb auf der anderen weiter. Die Anwendungen selbst liegen auf einer SSD, weil sie von kurzen Zugriffszeiten mehr haben als von Redundanz.
Die Mediathek dagegen zieht gerade auf eine einzelne 6-TB-Platte ganz ohne Spiegel um. Das ist kein Versäumnis, sondern eine Abwägung: Filme und Serien sind ersetzbar und zusätzlich an anderer Stelle gesichert. Ein Spiegel hätte hier die doppelte Plattenzahl gekostet, um etwas zu schützen, dessen Verlust nur Zeit kostet – und ein RAID ersetzt ohnehin kein Backup.
02 Cluster & Virtualisierung
Die drei Nodes bilden einen Proxmox-Cluster mit gemeinsamer Verwaltung und Quorum; Gäste lassen sich zwischen den Nodes umziehen. Die meisten Dienste laufen als LXC-Container statt als vollständige VMs: Container teilen sich den Host-Kernel und sind spürbar ressourcenschonender – wichtig bei den kleineren 4-GB-Nodes.
Vollwertige VMs kommen nur dort zum Einsatz, wo ein eigenes Betriebssystem nötig ist – zum Beispiel läuft der Webserver für genau diese Website als VM im Cluster.
03 Container & Dienste
Über den Cluster verteilt laufen 17 Gäste. Netzwerk & Sicherheit: AdGuard Home als filternder DNS-Server (plus eine zweite Instanz), Vaultwarden als Passwort-Tresor, ein Cloudflare-Tunnel für die öffentlichen Seiten und ein Mullvad-WireGuard-Exit-Node für privaten VPN-Ausgang.
Medien & Daten: Jellyfin und Emby als Medienserver, Nextcloud als private Cloud, Traccar fürs GPS-Tracking, dazu MeTube und iSponsorBlockTV. Für Metriken und Übersicht sorgen Beszel und Heimdall.
04 Zweiter DNS-Server
DNS ist im Heimnetz kritisch – fällt es aus, „geht das Internet nicht mehr". Deshalb läuft AdGuard doppelt: eine zweite Instanz auf einem anderen Node, die stündlich per adguardhome-sync gespiegelt wird. Filterlisten, Regeln und Einstellungen sind dort also jederzeit identisch, und die Instanz ist sofort einsatzbereit.
Ehrlich dazugesagt: Damit ein Ausfall im Alltag automatisch aufgefangen wird, muss der Router beide Server als DNS ausliefern – dieser letzte Schritt steht noch aus. Bis dahin ist die zweite Instanz ein vorbereiteter Ersatz, kein unterbrechungsfreier Failover.
05 Monitoring
Statt blind zu fliegen, überwacht Beszel den ganzen Cluster: ein schlanker Hub mit einem Agent auf jedem Node liefert CPU, RAM, Datenträger, Netzwerk und Temperaturen – bewusst leichtgewichtig gewählt, damals noch mit Blick auf zwei Nodes mit nur 4 GB RAM.
Weil ein „grüner" Node noch nicht heißt, dass auch jeder Dienst antwortet, ergänzt Uptime Kuma die zweite Ebene: Es fragt jeden Dienst aktiv an – Web-Oberflächen, Ports und die DNS-Auflösung – meldet Ausfälle samt Reaktionszeit und schickt bei Störungen automatisch eine E-Mail. Kurz: Beszel überwacht die Hardware, Uptime Kuma die Erreichbarkeit der Dienste. Ein dritter, selbst geschriebener Job meldet täglich, wenn irgendwo der Plattenplatz knapp wird – die Lücke war vorher echt.
06 Backups
Ein clusterweiter Job sichert jede Nacht automatisch alle Gäste per vzdump aufs TrueNAS, komprimiert und gestaffelt aufbewahrt: sieben tägliche, vier wöchentliche und drei monatliche Stände.
Dass die Sicherungen auch wirklich tragen, ist geprüft: Eine Sicherung wurde testweise als zusätzlicher Container zurückgespielt, hochgefahren und kontrolliert – erst danach gilt das Konzept für mich als belegt. Ein Backup, das man nie zurückgespielt hat, ist nur eine Vermutung.
07 Eigene Live-Dashboards
Das alte statische Dashboard ist zwei selbst gebauten Live-Dashboards gewichen, die ihre Werte direkt aus der Proxmox-API ziehen und sich jede Sekunde aktualisieren. Es gibt eine öffentliche Status-Ansicht mit zusammengefassten Zahlen und eine vollständige Übersicht, die ausschließlich im privaten Netz erreichbar ist. Eine kompakte Live-Übersicht ist zusätzlich direkt ins Portfolio eingebettet.
08 KI-Assistent im Cluster
Eine Besonderheit: Im Cluster läuft ein eigener KI-Assistent (Claude / Claude Code) in einem eigenen Container, erreichbar nur über das private Netz. Ein großer Teil des Ausbaus ist gemeinsam mit ihm entstanden: der Exit-Node, der zweite DNS-Server, das Monitoring, die Backups, die Dashboards und die automatischen Updates wurden zusammen geplant, gebaut und getestet – ebenso diese Website.
Interessant ist dabei weniger das Werkzeug als die Arbeitsweise: Ich lege fest, was entstehen soll, das Ergebnis wird gegen den echten Zustand geprüft und erst dann übernommen. Genau das ist der Teil, der sich auf jede andere Infrastruktur übertragen lässt.
09 Storage
Das NAS läuft auf TrueNAS Scale mit RAID 1 – alle Daten werden auf beide Platten gespiegelt, sodass beim Ausfall einer Festplatte nichts verloren geht. Der Speicher dient für allgemeine Dateien, Medien, als Backend für Nextcloud und als Ziel der nächtlichen Backups.
10 Netzwerk & Zugriff
Das Heimnetz hängt an einem handelsüblichen Router, ergänzt um einen zusätzlichen Access Point. Der Fernzugriff läuft über Tailscale, ein Mesh-VPN auf WireGuard-Basis – dafür muss kein einziger Port am Router geöffnet werden.
Die öffentlichen Seiten (Portfolio, Projekte, Status-Ansicht) werden über einen Cloudflare-Tunnel bereitgestellt: Auch dafür bleibt der Router zu, die Verbindung wird von innen nach außen aufgebaut. Alles andere – Verwaltungsoberflächen, das vollständige Dashboard, der Editor dieser Website – ist ausschließlich über das VPN erreichbar und nie öffentlich.
11 Herausforderungen
Tailscale in LXC-Containern braucht Handarbeit, da Container standardmäßig kein TUN-Gerät haben – das musste vom Host durchgereicht werden. Kniffliger war der Exit-Node: Der gewählte DNS-Server des VPN-Anbieters lag im selben CGNAT-Adressbereich, den Tailscale für sich beansprucht, wodurch dessen Anti-Spoofing die Antworten verwarf. Zwei Dienste, die beide auf denselben Adressraum bestehen – die Lösung lief am Ende darauf hinaus, die Paketfilterung von Tailscale und die eigene Weiterleitung sauber voneinander zu trennen.
Grundsatz bleibt: Alles, was keinen eigenen Kernel braucht, läuft als Container.
12 Aktueller Stand & nächste Schritte
Der Cluster läuft stabil im Dauerbetrieb: zweiter DNS-Server, Monitoring auf zwei Ebenen, automatische Backups mit geprüftem Restore, die Live-Dashboards und ein Reverse Proxy, der die internen Dienste unter sprechenden Namen mit gültigem Zertifikat erreichbar macht. Auch die Updates laufen automatisch – wöchentlich für die Pakete, und für die Dienste, die nicht aus der Paketverwaltung kommen, mit Snapshot davor und Rückrollen, falls danach etwas nicht mehr antwortet.
Als Nächstes: beide DNS-Server am Router hinterlegen, damit der Ausfall wirklich automatisch aufgefangen wird, echtes HA mit automatischem Failover (dafür fehlt bislang gemeinsamer Speicher bzw. Replikation) und VLANs zur Segmentierung des Netzes.
Diese Website
Portfolio, Projektseite und die öffentliche Status-Ansicht sind drei einzelne HTML-Seiten – ohne CMS, ohne Baukasten und ohne Build-Werkzeug. Sie liegen nicht bei einem Hoster, sondern werden von einem Webserver in meinem eigenen Cluster ausgeliefert.
Der Aufbau
Jede Seite ist eine eigene HTML-Datei: Struktur, Stile und Skripte stehen darin. Dazu kommen Schriften, Bilder und – auf dieser Projektseite – die 3D-Bibliothek samt Modell. Einen Build-Schritt gibt es nicht; der Server liefert die Datei so aus, wie sie geschrieben ist.
Aufbau, Gestaltung und Betrieb sind meine Entscheidungen. Wie der Code entstanden ist, steht in Kapitel 02.
01 Ohne CMS und Baukasten
Kein WordPress, kein Wix, kein React oder Vue: Struktur, Layout und Verhalten stehen direkt im Quelltext. Das war für mich der lehrreichere Weg, weil sich jede Zeile nachvollziehen lässt.
Ganz ohne fremden Code kommt die Seite trotzdem nicht aus: Der 3D-Viewer weiter oben nutzt Three.js. Das ist eine Abhängigkeit wie jede andere – sie liegt auf meinem eigenen Server, muss aber gepflegt und aktuell gehalten werden.
02 Wie die Seiten entstanden sind
Konzept, Struktur, Gestaltung und der gesamte Betrieb kommen von mir. Den Code habe ich größtenteils gemeinsam mit dem KI-Assistenten geschrieben, der im Homelab läuft (siehe Projekt 02): Ich lege fest, was entstehen soll, prüfe das Ergebnis und übernehme es erst, wenn es passt. Der Editor aus Kapitel 07 ist genauso entstanden.
03 Gestaltung und Bedienung
Alle Seiten teilen dieselbe Bildsprache: dunkle Fläche, ein warmer Akzentton, drei aufeinander abgestimmte Schriften und große Ghost-Nummern hinter den Abschnitten. Inhalte blenden beim Scrollen ein, im Hintergrund laufen dezente Licht- und Faser-Effekte.
Weil das auf schwächeren Geräten stören kann, lassen sich die Effekte oben rechts abschalten; die Einstellung bleibt im Browser gespeichert. Wer im Betriebssystem „weniger Bewegung“ eingestellt hat, bekommt die Animationen automatisch nicht. Das Layout ist für große Bildschirme entworfen und über Umbruchpunkte an Tablet und Handy angepasst.
04 Drei Seiten, ein System
Das Portfolio als Startseite, diese Projektseite für die Details und eine öffentliche Status-Ansicht des Homelabs. Alle drei nutzen dieselben Design-Bausteine; Impressum und Datenschutzerklärung sind im selben Stil gehalten.
05 Live-Daten aus dem eigenen Cluster
Im Portfolio zeigt ein Abschnitt den aktuellen Zustand des Homelabs: Auslastung, laufende Dienste und eine Verlaufskurve, jede Sekunde aktualisiert. Die Zahlen stammen aus der Verwaltungsschnittstelle des Clusters.
Was öffentlich sichtbar ist, wird vorher reduziert: nur zusammengefasste Werte und Dienstnamen, keine Adressen und keine internen Angaben. Die vollständige Übersicht läuft getrennt davon und ist nur aus meinem privaten Netz erreichbar.
06 3D-Modell direkt im Browser
Das Gehäuse aus dem NFC-Projekt lässt sich weiter oben drehen und zoomen. Gerendert wird die tatsächliche Druckdatei aus dem CAD-Export, die Beleuchtung ist auf die Farben der Seite abgestimmt.
Das kostet Ladezeit: Bibliothek und Modell zusammen sind mit gut zwei Megabyte der mit Abstand größte Teil dessen, was diese Seite überträgt. Beides liegt deshalb auf dem eigenen Server statt bei einem CDN, und das Rendering pausiert automatisch, sobald der Viewer aus dem Bild gescrollt ist.
07 Ein eigener Editor für die Inhalte
Damit Textänderungen keine Handarbeit in der Datei bedeuten, gibt es einen kleinen Inline-Editor – geschrieben in Python, nur mit der Standardbibliothek, ohne Zusatzpakete. Man klickt im echten Layout auf einen Text oder ein Bild und ändert ihn dort, wo er später auch steht.
Beim Speichern wird die Seite nicht neu erzeugt, sondern nur die betroffene Stelle in der Datei ersetzt; Formatierung und Kommentare bleiben dadurch unverändert. Vor jeder Änderung legt der Editor eine Sicherung an. Erreichbar ist er ausschließlich im privaten Netz und zusätzlich mit Passwort geschützt.
08 Betrieb und Datenwege
Ausgeliefert wird von nginx auf einer virtuellen Maschine im eigenen Proxmox-Cluster. Nach außen geht es über einen Cloudflare-Tunnel, dadurch muss am Router kein Port geöffnet werden und der Server ist aus dem Internet nicht direkt ansprechbar.
Cloudflare ist damit an jedem Aufruf beteiligt und verarbeitet die IP-Adresse der Besucher – das steht so auch in der Datenschutzerklärung. Schriften und Dienst-Icons liegen dagegen auf dem eigenen Server, es wird also nichts von fremden CDNs nachgeladen; Bilder lädt der Browser erst, wenn sie gebraucht werden. Die Maschine wird nachts mitgesichert, ihre Erreichbarkeit überwacht das Monitoring aus dem Homelab-Projekt.
Aufnahmen aus dem laufenden Betrieb – die Zahlen darin kommen aus dem eigenen Cluster.


Das Rack-Display
Ein Touch-Panel im Rack, das auf einen Blick zeigt, wie es dem Cluster geht – und über das sich Maschinen im Notfall auch schalten lassen. Angetrieben von einem Raspberry Pi der dritten Generation, also von Hardware, die für Webseiten eigentlich zu schwach ist. Genau daran war das Projekt lehrreich.
Der Aufbau
Ein einzelnes Python-Skript ohne Fremdpakete bedient zwei Aufgaben: Es liefert die Oberfläche aus und sammelt im Hintergrund die Zahlen aus fünf Quellen ein – dem Cluster, der Zugriffsstatistik der Website, der Erreichbarkeitsprüfung, dem DNS-Filter und dem Pi selbst. Angezeigt wird das Ganze von einem Browser im Vollbild, gestartet beim Hochfahren.
Der Bildschirm ist breit und flach: 1280 zu 400 Punkte. Das prägt jede Gestaltungsentscheidung.
01 Zum Hinsehen, nicht zum Lesen
Ein Display im Rack wird im Vorbeigehen angeschaut, nicht studiert. Der Hauptschirm zeigt deshalb drei Panels und darunter drei Kacheln, die je einen ganzen Bereich auf eine Zahl zusammenziehen. Ob etwas nicht stimmt, steht als Klartext im Kopf – man muss keine Liste durchgehen.
Vorher stand dort die vollständige Dienstliste als Wand aus Kürzeln: über zwanzig Einträge, die man einzeln lesen musste, um zu bemerken, dass einer fehlt. Das war Information ohne Aussage.
02 Details erst auf Druck
Jede der drei Kacheln öffnet eine Vollbild-Ansicht. Eine listet alle geprüften Dienste, Ausfälle zuerst und danach nach Antwortzeit sortiert. Eine zeigt den DNS-Verkehr des Netzes samt blockiertem Anteil. Die dritte dient zum Schalten.
03 Schaltflächen, die man nicht versehentlich trifft
In der Steuerung hingen die Knöpfe zuerst an jeder Zeile: siebzehn Maschinen mal drei Schaltflächen, alle gleich groß, alle jederzeit scharf. Auf einem Touchscreen in Hüfthöhe ist das eine Einladung zum Fehlgriff.
Jetzt gibt es die Schaltflächen nur einmal, an fester Stelle, und sie erscheinen erst, wenn etwas ausgewählt ist. Nochmaliges Antippen hebt die Auswahl wieder auf.
04 Schalten geht nur direkt am Panel
Die Steuerbefehle nimmt der Dienst ausschließlich vom Gerät selbst entgegen; jede Anfrage von außen wird abgewiesen. Ansehen darf man das Panel im Heimnetz, schalten nur, wer davorsteht – die Zugangskontrolle ist der physische Zugriff auf das Rack.
Zusätzlich sind die Eingriffe abgestuft: Herunterfahren ist der normale Weg, das harte Abschalten bleibt hängenden Maschinen vorbehalten, und Eingriffe an einem ganzen Knoten fragen zweimal nach.
05 Was die Hardware erzwingt
Der Pi hat keine Grafikbeschleunigung im Browser. Über fünf Ansätze nachgemessen: jede dauerhafte Animation kostet rund 80 % eines Rechenkerns und 8 °C – unabhängig davon, was sich bewegt, wie oft und wie groß. Im Leerlauf sind es 42 % und 55 °C.
Deshalb enthält die Oberfläche bewusst keine laufenden Animationen und keine Übergänge. Die Seite wird einmal aufgebaut, danach werden nur noch geänderte Werte geschrieben. Auch die Vollbild-Ansichten zeichnen sich nur neu, wenn sich ihr Inhalt wirklich geändert hat – sonst würde die Aktualisierung alle paar Sekunden das ganze Fenster neu malen.
Der zweite verbreitete Browser schied ganz aus: Er startet, verbraucht einen vollen Kern und zeichnet trotzdem kein Bild, weil der Grafikkern die benötigte Schnittstelle nicht liefert.
06 Ein Display, das stillschweigend abschneidet
Die Seite ist hart auf die Maße des Panels gesetzt, ohne Rollbalken. Was zu hoch gerät, wird nicht gescrollt und nicht gemeldet – es fehlt einfach. Genau das ist passiert: vier Punkte zu hoch, und die unterste Zeile war abgeschnitten, ohne dass es auf einem großen Bildschirm aufgefallen wäre.
Die Kachelraster addieren ihre Zeilenhöhen deshalb nicht mehr, sondern teilen den Platz, den sie bekommen. Kommt ein Dienst dazu, werden die Karten flacher statt unsichtbar. Und beim Ändern des Layouts wird nachgemessen, nicht geschätzt.
07 Eine Zahl, die nichts aussagt
In der Netz-Ansicht steht die Liste der anfragenden Geräte bewusst nur als Randnotiz. Die Geräte im Heimnetz fragen nämlich den Router, und der leitet gesammelt an den DNS-Filter weiter – der sieht deshalb zu über 99 % nur den Router selbst.
Die Liste sagt also etwas über den Weg der Anfragen aus, aber nichts über die Geräte. Sie prominent zu zeigen, hätte eine Genauigkeit vorgetäuscht, die nicht da ist.
Aufnahmen vom laufenden Panel – in der Auflösung, in der es im Rack hängt.

