Wenn du bereits entdeckt hast, was mit dem Raspberry Pi alles möglich ist, die passende Hardware ausgewählt, das System eingerichtet und dich mit den Grundlagen von Linux vertraut gemacht hast – dann ist es Zeit für den nächsten Schritt. Im letzten Teil unserer Serie steigen wir in die praktische Webentwicklung ein. Du bekommst konkrete Tipps und eine Schritt-für-Schritt-Anleitung, wie du deinen Raspberry Pi in einen zuverlässigen, sicheren und einfach zu wartenden Webserver verwandelst.
Wie bringen wir unseren Service ins Web
Beim Deployment einer Anwendung in die Produktionsumgebung stößt man auf zahlreiche Fragen und Entscheidungen – die Antworten darauf hängen stark vom jeweiligen Projekt, der verwendeten Technologie und den angestrebten Zielen ab. Es handelt sich um ein Thema, das zu umfangreich ist, um es in einem einzigen Artikel vollständig abzudecken. Daher soll dieser Artikel eher als Übersicht über die wichtigsten Bereiche dienen, um dir eine erste Orientierung zu geben – als Vorbereitung für weiteres Selbststudium und Experimentieren. Wir werfen einen Blick auf Themen wie:
- Wie bringt man die Anwendung auf das Gerät?
- Wie stellt man den unterbrechungsfreien Betrieb der Anwendung sicher?
- Wie stellt man die Anwendung öffentlich zugänglich ins Netzwerk?
- Wie automatisiert man Build- und Deployment-Prozesse (CI/CD)?
- Wie überwacht man den Zustand der Anwendung?
- Worauf sollte man aus Sicherheitsgründen achten?
Ein Hinweis: In den folgenden Abschnitten betrachten wir den gesamten Prozess hauptsächlich aus der Perspektive des Hostings eines Backend-Services. Wenn es nur darum geht, statische Webseiten oder SPA-Anwendungen zu hosten, die clientseitig gerendert werden, entfällt ein Teil der Komplexität – denn in diesem Fall liefert der Server lediglich fertige Dokumente und Assets auf Anfrage aus, ohne weitere serverseitige Verarbeitung.

Wie bringt man die Anwendung auf das Gerät?
Sobald wir eine Webanwendung erstellt haben, besteht die erste Herausforderung darin, sie auf den Raspberry Pi zu bringen. Am einfachsten ist es, auf Git zu setzen: Du klonst das Repository direkt auf dem Gerät, installierst die Abhängigkeiten, kompilierst den Code und startest die Anwendung – genau wie in der Entwicklungsumgebung. Diese Methode ist unkompliziert, bringt aber gewisse Einschränkungen mit sich – vor allem bei komplexeren oder anspruchsvolleren Projekten, bei denen aufwändigere Abhängigkeiten konfiguriert werden müssen oder wo die Konsistenz zwischen Entwicklungs- und Produktionsumgebung entscheidend ist.
Wenn du eine robustere Lösung benötigst oder sicherstellen willst, dass die Anwendung in einer isolierten und exakt definierten Umgebung läuft, sind Docker-Container die ideale Methode zur Bereitstellung. Docker ermöglicht es dir, die Anwendung zusammen mit all ihren Abhängigkeiten in einem einzigen Image zu verpacken. Dieses kann dann überall dort ausgeführt werden, wo Docker läuft. Die Grundlage bildet eine Dockerfile
-Datei, die als Rezept für die Erstellung des Images dient. Hier ein Beispiel für eine einfache Node.js-Anwendung (basierend auf dem offiziellen node:18
Image):

Das fertige Image wird anschließend in ein Container-Registry hochgeladen, zum Beispiel auf Docker Hub oder in das GitHub Container Registry (letzteres ist in der kostenlosen Version deutlich großzügiger):
docker login
docker build -t /: .
docker push /:
Auf dem Raspberry Pi kannst du das Image mit einem einzigen Befehl herunterladen und starten. Der Parameter -p 8080:3000
dient dazu, den Port außerhalb des Containers verfügbar zu machen – der Dienst ist damit unter der lokalen Adresse http://localhost:8080
erreichbar:
docker run -d -p 8080:3000 /:
Für komplexere Anwendungen, die aus mehreren Schichten bestehen (z. B. Webserver, Datenbank, lokales Dateisystem), ist die Datei docker-compose.yml
ein äußerst hilfreiches Werkzeug. Sie definiert alle Dienste eines Projekts sowie deren Verknüpfung untereinander:

Alle Dienste kannst du anschließend mit einem einzigen Befehl starten:
docker compose up -d
Das war nur ein einfaches Beispiel, aber wenn du dir gerne das Leben erleichterst, lohnt sich ein Blick in die Welt von Docker auf jeden Fall.
Wie stellt man den unterbrechungsfreien Betrieb der Anwendung sicher?
Sobald du vom lokalen Entwicklungsumfeld zur „echten“ Produktivumgebung übergehst, wird jeder Ausfall der Anwendung zum Problem. Beim Einsatz auf dem Raspberry Pi ist es daher entscheidend, dass deine Anwendung bei unerwarteten Abstürzen oder nach einem Neustart des Geräts automatisch wieder startet.
Eines der am weitesten verbreiteten und zugleich einfachsten Werkzeuge dafür ist systemd
, das in den meisten Linux-Distributionen (einschließlich Raspberry Pi OS) bereits integriert ist. Mit systemd
lässt sich eine einfache Service-Datei definieren, die den Lebenszyklus der Anwendung steuert: Start beim Systemboot, automatischer Neustart nach einem Absturz, Begrenzung des Ressourcenverbrauchs und einfacher Zugriff auf Logs. Eine grundlegende Konfiguration könnte zum Beispiel so aussehen:

Mit dieser kurzen Konfigurationsdatei erreichst du, dass die Anwendung beim Systemstart automatisch gestartet wird und sich nach jedem Absturz nach 5 Sekunden neu startet. Anschließend kannst du den Dienst mit folgenden Befehlen aktivieren und starten:
sudo systemctl daemon-reload
sudo systemctl enable .service
sudo systemctl start .service
Ein großer Vorteil von systemd
ist die einfache Konfiguration und die geringe Systembelastung – ideal für den Einsatz auf leistungsschwächeren Geräten.
Wenn deine Anwendung als Docker-Container läuft, ist der Vorgang sogar noch einfacher. Du musst lediglich den Startbefehl für den Container um den Parameter --restart unless-stopped
ergänzen:
docker run -d --restart unless-stopped /:
Alternativ kannst du die Zeile restart: unless-stopped
zu den Diensten in deiner docker-compose.yml
-Datei hinzufügen. In beiden Fällen kannst du sicher sein, dass deine Anwendung zuverlässig läuft – mit minimalem manuellem Aufwand, selbst bei unerwarteten Zwischenfällen.
Wie macht man eine Anwendung im öffentlichen Netzwerk zugänglich?
In manchen Fällen reicht es völlig aus, wenn die Anwendung nur im lokalen Netzwerk erreichbar ist – etwa bei der Heimautomatisierung. Wenn du deinen Dienst jedoch öffentlich zugänglich machen willst, musst du dich mit Themen wie Netzwerktechnik, DNS und Sicherheit auseinandersetzen.
Traditionell wird eine Anwendung über Portweiterleitung (Port Forwarding) im Router zugänglich gemacht. Solange sich das Raspberry Pi-Gerät nur im Heimnetz befindet, ist es von außen durch den Router „versteckt“. Durch Portweiterleitung kannst du einen Port von der öffentlichen IP-Adresse deines Routers an die interne IP deines Raspberry Pi weiterleiten. In Kombination mit einem DynDNS-Dienst (Dynamic DNS) musst du dich nicht darum kümmern, dass dein Anbieter die IP-Adresse regelmäßig ändert – DynDNS ordnet die dynamische IP automatisch einer festen Domain zu.
Diese Lösung eignet sich allerdings nur für Personen, die wirklich genau wissen, was sie tun! Du machst damit dein Heimnetz öffentlich zugänglich, was ein großes Sicherheitsrisiko darstellt. Außerdem erlauben viele Provider die Öffnung bestimmter Ports gar nicht mehr oder nur mit Einschränkungen.
Eine einfachere, schnellere und sicherere Lösung – insbesondere für kleinere Projekte – ist es, auf einen Drittanbieterdienst wie den kostenlosen Cloudflare Tunnel zu setzen. Dabei handelt es sich um ein Reverse-Proxy-Tunneling: Die Anwendung auf deinem Pi baut eine ausgehende Verbindung zu Cloudflare auf, über die – und über die Infrastruktur von Cloudflare – dein Dienst sicher im öffentlichen Internet bereitgestellt wird. Du musst dabei keine Ports am Router öffnen.
Voraussetzung ist der Besitz einer Domain (diese muss nicht zwingend bei Cloudflare registriert sein), aber die wirst du ohnehin brauchen, wenn du deinen Dienst unter einer seriös wirkenden Adresse bereitstellen möchtest. Und mit Cloudflare Tunnel bekommst du noch weitere Vorteile dazu: Der Tunnel ist verschlüsselt, schützt vor gängigen DDoS-Angriffen und bietet ein kostenloses HTTPS-Zertifikat.
Damit umgehst du viele sicherheitsrelevante, netzwerktechnische und rechtliche Hürden – und vor allem: Dein Gerät ist nicht „nackt“ im Internet sichtbar.

Brauche ich einen Reverse-Proxy-Webserver? (Nginx, Apache)
Ein Reverse-Proxy ist eine Art Server, der Anfragen aus dem Internet entgegennimmt und an eine interne Anwendung weiterleitet. Wenn wir einen Backend-API-Dienst entwickeln, fungiert dieser selbst als HTTP-Server. Er läuft typischerweise auf einem bestimmten Port (z. B. 3000) und kann Anfragen direkt bedienen – ohne einen zusätzlichen Vermittler. Webserver wie Nginx oder Apache bieten jedoch eine wertvolle Zwischenschicht, die viele Low-Level-Aufgaben übernimmt: Caching, Rate-Limiting, Schutz vor Brute-Force- und DoS-Angriffen, grundlegendes Logging, Monitoring, HTTPS-Zertifikate usw.
Allerdings kann es sein, dass du diese Funktionen in kleineren Projekten gar nicht brauchst oder sie direkt in deiner Backend-Anwendung selbst implementierst. Alternativ können Dienste wie Cloudflare oder andere externe Lösungen diese Aufgaben für dich übernehmen.
Andererseits – wenn es nicht darum geht, einen dynamischen API-Dienst bereitzustellen, sondern lediglich eine statische Website oder eine Single-Page-Anwendung (SPA) zu hosten, genügt ein Nginx- oder Apache-Server vollkommen – ganz ohne separate Backend-Anwendung. Diese Server können statische Dateien (HTML, CSS, JS, Bilder) effizient und zuverlässig direkt von der Festplatte ausliefern.
Selbst wenn ein Backend vorhanden ist, ist es oft sinnvoll, das Frontend als eigenen, unabhängigen Prozess auf einem anderen Port (oder sogar auf einem anderen Server) bereitzustellen. Das sorgt für eine bessere Trennung zwischen Frontend und Backend, vereinfacht CI/CD-Prozesse, erhöht Sicherheit und Performance und ermöglicht einfacheres Skalieren.
Wie automatisiert man Build- und Deployment-Prozesse?
Jeder manuelle Schritt kostet wertvolle Zeit und erhöht zugleich das Fehlerrisiko. Je komplexer ein Projekt wird, desto leichter ist es, beim Deployment etwas zu übersehen. Die Lösung heißt CI/CD (Continuous Integration / Continuous Deployment) – ein System, bei dem jeder Push ins Repository automatisch eine Reihe von Aufgaben auslöst (Build, Test, Deployment), ganz ohne menschliches Zutun.
Für kleinere Projekte reichen GitHub Actions oder GitLab CI/CD völlig aus. Dort beschreibst du die einzelnen Schritte des Prozesses in einer YAML-workflow
-Datei. Zum Beispiel kannst du so nach jedem Push in den main
-Branch automatisch ein neues Image deployen:

Auf dem Raspberry Pi kannst du das Herunterladen des aktuellen Images z. B. mit dem Tool Watchtower automatisieren. Dafür musst du deine docker-compose.yml
-Konfiguration nur um Folgendes erweitern:

Wenn du kein Docker verwendest und z. B. nur eine automatische Aktualisierung deines Dienstes einrichten möchtest, kannst du auf dem Raspberry Pi ein einfaches Skript erstellen, z. B. deploy.sh
, das die neueste Version deiner Anwendung herunterlädt und startet…

…das du anschließend z. B. mit einem CRON-Job (geplante, regelmäßig wiederkehrende Aufgabe) jede Nacht ausführen lassen kannst (im Beispiel unten jede Nacht um 3:00 Uhr):
0 3 * * * /home///deploy.sh >> /home///deploy.log 2>&1
Alternativ kannst du das Skript direkt aus GitHub Actions per SSH ausführen lassen.
Wie überwacht man den Zustand einer Anwendung?
Die Anwendung zu deployen ist nur die halbe Miete. Die andere Hälfte besteht darin, zu wissen, was darin passiert und wie sie sich in Echtzeit verhält. Monitoring ist kein „Nice-to-have“ – es ist eine Grundvoraussetzung für den zuverlässigen Betrieb jeder produktiven Umgebung. Wenn du weißt, was in der Anwendung und auf dem Server geschieht (oder eben nicht geschieht), kannst du Fehler beheben, bevor sie jemand bemerkt.
Systemlogs
Wenn du deine Anwendung über systemd startest, kannst du die aktuellen Logs mit dem Befehl journalctl -u -f
anzeigen. Dabei steht -u
(unit) für den spezifischen Dienstnamen und -f
(follow) zeigt neue Logeinträge in Echtzeit an. Bei containerisierten Diensten bekommst du eine ähnliche Ansicht mit docker logs
, oder – falls du docker compose
verwendest – mit docker compose logs -f
für alle Container gleichzeitig.
Diese Befehle ermöglichen es dir, Starts, Fehler und weitere Ereignisse der Anwendung schnell zu verfolgen. Sobald die Anwendung läuft, werden Logs zu deiner wichtigsten Informationsquelle. Überwache sie regelmäßig, automatisiere ihre Bereinigung und behalte stets im Blick, wo und wie sie gespeichert werden – denn Chaos in den Logs rächt sich genau dann, wenn du es am wenigsten gebrauchen kannst.
Automatisierte Status- und Verfügbarkeitsüberwachung
Es geht jedoch nicht nur um Logausgaben – oft musst du frühzeitig erkennen, wenn etwas nicht mehr funktioniert. Für einfaches Alerting reichen UptimeRobot oder das selbst gehostete Uptime Kuma aus. Diese Tools prüfen in regelmäßigen Abständen, ob Web- oder API-Dienste von außen erreichbar sind, und benachrichtigen dich sofort bei einem Ausfall – per E-Mail, SMS oder Push-Benachrichtigung.

Die meisten modernen Backend-Dienste bieten einen eigenen Endpoint wie /health
oder /status
an, der nicht nur die Erreichbarkeit prüft, sondern auch den Zustand von Datenbank, externen Diensten oder Job-Queues. Wenn du einen solchen Endpoint noch nicht hast, solltest du ihn hinzufügen und regelmäßig von deinem Monitoring-Tool überprüfen lassen. So bekommst du nicht nur bei einem kompletten Ausfall deines Servers eine Warnung, sondern auch dann, wenn ein kritischer Teil der Anwendung nicht mehr korrekt funktioniert.
Erweiterte Metriken und Visualisierungen
Systemlogs und Verfügbarkeitsüberwachung stellen nur das absolute Minimum dar. Einen umfassenderen Einblick in den Zustand deiner Anwendung erhältst du erst durch Metriken, die z. B. die Auslastung von CPU und RAM, Antwortzeiten oder den Zustand von Abhängigkeiten über eigene /metrics
-Endpoints sichtbar machen. Am häufigsten kommen hierfür Prometheus in Kombination mit Grafana zum Einsatz – diese ermöglichen das Sammeln und Visualisieren aller wichtigen Daten an einem zentralen Ort.
Für die Überwachung von Fehlern und Ausnahmen im Code ist ein Dienst wie Sentry besonders hilfreich. Er erfasst detaillierte Informationen zu jedem Fehler sowie den Kontext, in dem dieser aufgetreten ist.

Überlege dir jedoch gut, wie viel Komplexität du zu Beginn wirklich brauchst. Jede zusätzliche Schicht bedeutet mehr Aufwand bei der Wartung und höhere Anforderungen an das System. Wenn du ein kleines Projekt startest, genügt es vollkommen, zunächst mit einfachen Logs und grundlegender Verfügbarkeitsüberwachung zu beginnen. Sobald die Anwendung wächst, kannst du dein Monitoring bedarfsgerecht erweitern.
Worauf sollte man aus Sicherheitsgründen achten?
Der Raspberry Pi ist ein kleines, sympathisches Gerät – aber in Sachen Sicherheit gelten dieselben Regeln wie bei „großen“ Servern: Jedes Gerät, das aus dem Internet erreichbar ist, stellt ein potenzielles Angriffsziel dar. Ohne grundlegende Sicherheitsmaßnahmen wirst du früher oder später Probleme bekommen.
- Sorge für regelmäßige Sicherheitsupdates. Unter Raspberry Pi OS (oder anderen Debian-basierten Systemen) hilft dir das Paket
unattended-upgrades
, Sicherheitsaktualisierungen automatisch – also ohne manuelles Eingreifen – einzuspielen:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
- Aktualisiere auch hin und wieder auf größere Paketversionen und die Firmware deines Raspberry Pi. Vor einem größeren Upgrade solltest du jedoch unbedingt ein Backup wichtiger Daten und Konfigurationen erstellen – falls etwas schiefgeht, hast du so eine Möglichkeit zur Wiederherstellung.
sudo apt update
sudo apt full-upgrade
sudo rpi-eeprom-update
sudo reboot
- Deaktiviere die Passwortanmeldung für SSH und aktiviere nur die Anmeldung per SSH-Schlüssel. Vermeide die Nutzung von Standardkonten (z. B.
pi
) – am besten benennst du sie um, deaktivierst oder löschst sie ganz. Nach einer Änderung der SSH-Konfiguration nicht vergessen, den SSH-Dienst mitsudo systemctl restart ssh
neu zu starten.
# /etc/ssh/sshd_config
PasswordAuthentication no
PermitRootLogin no
- Isoliere Anwendungen vom System. Deine Anwendung sollte nicht unter dem Root-Benutzer laufen. Richte sie so ein, dass sie unter einem weniger privilegierten Benutzer mit eingeschränkten Rechten ausgeführt wird. Wenn du Docker verwendest, ist die Anwendung bereits prinzipiell isoliert, aber achte auch hier darauf, sichere Einschränkungen explizit festzulegen (Benutzer, Berechtigungen, Ressourcenlimits).
- Regelmäßige Backups sind deine beste Versicherung. Erstelle regelmäßig Sicherungen (z. B. per Cron-Job) – von Datenbanken, Konfigurationsdateien, Zertifikaten und dem Anwendungscode. Speichere die Backups außerhalb des Geräts an einem sicheren Ort (z. B. in einem entfernten Speicher oder in der Cloud). Prüfe gelegentlich, ob du ein Backup auch tatsächlich wiederherstellen kannst.
Der Weg geht weiter
Der Raspberry Pi ist ein kleines Hardware-Wunder – und in den Händen eines Entwicklers kann er sich in eine vollwertige Webinfrastruktur, einen Ideeninkubator oder ein Einstiegstor in die Welt von DevOps verwandeln. Auf dem Weg dorthin lernst du den Umgang mit Logs, Monitoring, Grundlagen der Netzwerktechnik und Sicherheits-Hygiene – Fähigkeiten, die dir in jedem beruflichen oder privaten Projekt zugutekommen werden.
Wie bereits eingangs erwähnt, konnte dieser Artikel nicht alles abdecken. Themen wie unterbrechungsfreie Stromversorgung (UPS), erweiterte Sicherheit, Rollbacks, verschiedene Deployment-Strategien oder Skalierung haben wir bewusst außen vor gelassen. Ich hoffe aber, dass du dich zumindest in den grundlegenden Bereichen gut orientieren konntest und eine solide Grundlage für weitere Experimente und Selbststudium erhalten hast.

Wenn du bis hierher gelesen hast – oder deine Anwendung sogar schon läuft – ist das ein großer Erfolg! Vielleicht stößt du eines Tages an die Grenzen deines einfachen „Heimservers“: Die Datenbank wird langsamer, die SD-Karte verschleißt, der Arbeitsspeicher kommt an seine Grenzen. Aber nimm das als Zeichen dafür, dass dein Projekt an Fahrt aufgenommen hat. Dann ist es an der Zeit, über den Wechsel auf einen leistungsfähigeren Server, in die Cloud oder zu einem spezialisierten Hoster nachzudenken. Oder du stellst fest, dass sich selbst mit dem Pi – durch effizienten Ressourceneinsatz oder ein kleines Heim-Cluster – deutlich mehr erreichen lässt, als du gedacht hättest. Wohin auch immer deine nächsten Schritte führen – ich wünsche dir viel Erfolg und gutes Gelingen!

Tomáš Bencko
Der Autor dieses Artikels ist Tomáš, ein Frontend-Entwickler mit Fokus auf React, Vue.js und TypeScript. Seine Aufgabe ist es, moderne und skalierbare Frontend-Lösungen zu schaffen – und das nicht nur auf technischer Ebene, sondern auch mit einem ausgeprägten Gespür für Design. Neben der Arbeit für Kunden sucht er ständig nach Möglichkeiten, die Teamarbeit effizienter zu gestalten, experimentiert mit KI und Automatisierung und bringt neue Ideen ein, die sowohl Projekte als auch seine Kolleg:innen voranbringen.