SLC_Game/04_Tablet-Quiz/app/DEPLOY.md
breitenbach76 029a12151e Feedback-Collector serverfest: Datenpfad konfigurierbar + Doku fuer php-fpm
Vorbereitung fuer Server-Deploy (Server hat kein PHP; nginx vorhanden, PHP 8.3 im Repo installierbar):

- feedback.php: Datenverzeichnis ueber Env SLC_FEEDBACK_DIR ueberschreibbar
  (empfohlen ausserhalb des Web-Roots -> keine git-pull-Konflikte, .jsonl nicht
  oeffentlich). Default unveraendert ./feedback-data. Weiterhin NUR PHP-Core noetig,
  keine Extensions.
- .gitignore: 04_Tablet-Quiz/app/feedback-data/ ausgenommen (falls Default-Pfad).
- DEPLOY.md: konkrete Schritte fuer Ubuntu 24.04 + nginx (apt install php-fpm,
  Socket php8.3-fpm, NUR feedback.php als PHP ausfuehren = Hardening, feedback-data
  per deny all schuetzen, SLC_FEEDBACK_DIR setzen) + curl-Verifikation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 09:04:41 +02:00

5.7 KiB

Deployment — SLC-Workshop Companion (App)

Auftrag für die Server-Claude / Ops: Diese App statisch ausliefern. Kein Build-Schritt, keine Secrets, keine Datenbank.

Neu (v0.10): kleiner Feedback-Endpoint. Die App sammelt jetzt Workshop-Feedback (Phasen + Prüfschritte) und speichert es auf dem Server zur späteren Auswertung. Dafür braucht es einen schlanken POST-Sammelpunkt (Flat-File, keine Datenbank). Referenz liegt bei: feedback.php. Ist der Endpoint (noch) nicht aktiv, geht nichts verloren: die App hält das Feedback lokal vor (Retry-Queue) und der Header-Button „⇩ Feedback" exportiert es als Backup-Datei.

Was das ist

  • Eine statische Single-Page-PWA. Alle Inhalte (Stationen, Quiz, Use-Cases) sind in index.html eingebettet — keine Laufzeit-API nötig.
  • Dateien im Ordner 04_Tablet-Quiz/app/:
    • index.html — die App
    • manifest.webmanifest — PWA-Manifest
    • sw.js — Service Worker (Offline-Cache der App-Shell)
    • icon.svg — App-Icon
    • feedback.phpoptionaler Feedback-Sammelpunkt (Flat-File, JSON Lines)

Ziel

Den Ordner 04_Tablet-Quiz/app/ als statisches Web-Root über den vorhandenen Webserver bereitstellen, erreichbar per HTTPS (oder localhost).

Wichtig: Der Service Worker (Offline/Installierbar) läuft nur über HTTPS oder localhost. Über reines http:// ohne TLS registriert er sich nicht — die App funktioniert dann trotzdem, nur ohne Offline-Cache.

Schritte

  1. Repo auf dem Server bereitstellen/aktualisieren: git clone https://git.1789.cloud/patrick/SLC_Game.git (bzw. git pull).
  2. Den Ordner SLC_Game/04_Tablet-Quiz/app/ als statisches Root einbinden.

Beispiel nginx

server {
  listen 443 ssl;
  server_name slc.example.intern;            # anpassen
  # ssl_certificate ... ; ssl_certificate_key ... ;
  root /srv/SLC_Game/04_Tablet-Quiz/app;      # Pfad anpassen
  index index.html;
  location = /sw.js { add_header Cache-Control "no-cache"; }   # SW immer frisch
  location / { try_files $uri $uri/ /index.html; }
}

Beispiel Caddy (TLS automatisch)

slc.example.intern {
  root * /srv/SLC_Game/04_Tablet-Quiz/app
  file_server
  header /sw.js Cache-Control "no-cache"
}

Feedback-Endpoint (empfohlen — für die Auswertung)

Die App schickt jedes gespeicherte Feedback per POST als JSON an den im <meta name="slc-feedback-endpoint"> hinterlegten Pfad (Default: feedback.php, gleiche Domain). Der Service Worker fasst POSTs nicht an — der Offline-Cache stört also nicht.

Variante A — PHP (empfohlen, mit nginx der kürzeste Weg). feedback.php braucht nur den PHP-Core (json + Datei-I/O) — keine Extensions (kein php-mysql/curl/mbstring).

Konkret auf Ubuntu 24.04 + nginx (PHP ist dort nicht vorinstalliert, aber 8.3 im Repo):

sudo apt install php-fpm                       # zieht php8.3-fpm; Socket: /run/php/php8.3-fpm.sock
# Datenverzeichnis AUSSERHALB des Web-Roots anlegen und dem nginx/php-User geben:
sudo mkdir -p /srv/slc-feedback && sudo chown www-data:www-data /srv/slc-feedback
# im server{}-Block der SLC-App:
# 1) NUR feedback.php als PHP ausführen (kein generelles .php — Hardening):
location = /feedback.php {
  include fastcgi_params;
  fastcgi_pass unix:/run/php/php8.3-fpm.sock;            # Pfad ggf. anpassen
  fastcgi_param SCRIPT_FILENAME $document_root/feedback.php;
  fastcgi_param SLC_FEEDBACK_DIR /srv/slc-feedback;      # Daten ausserhalb des Web-Roots
}
# 2) Datenverzeichnis im Web-Root (Fallback) niemals ausliefern:
location ^~ /feedback-data/ { deny all; return 404; }

Daten landen als JSON Lines in $SLC_FEEDBACK_DIR/feedback.jsonl (eine Zeile pro Feedback) → für die Auswertung einlesen / zu CSV konvertieren. Ohne gesetzte SLC_FEEDBACK_DIR schreibt das Skript nach ./feedback-data/ (per .gitignore ausgenommen, von nginx via Regel 2 nicht ausgeliefert).

Verifikation: curl https://<host>/feedback.php{"ok":true,...}. Nach einem gespeicherten Feedback wächst feedback.jsonl um eine Zeile.

Variante B — kein PHP verfügbar. Endpoint auf einen beliebigen JSON-POST-Empfänger zeigen lassen (z. B. ein kleines Node-/Worker-Skript, das den Body an eine Datei anhängt) und im <meta name="slc-feedback-endpoint"> dessen URL eintragen.

Variante C — gar kein Server-Save. Auch ohne Endpoint funktioniert alles: das Feedback bleibt in der Retry-Queue und kann über den Header-Button „⇩ Feedback" als JSON-Datei exportiert werden.

Verifikation nach dem Deploy

  1. URL öffnen → Startbildschirm „SLC Companion".
  2. DevTools → Application → Service Workers: sw.js ist activated.
  3. Flugmodus/Offline → Seite neu laden → App lädt weiterhin (Offline-Cache).
  4. Einen Major-Durchlauf spielen, an einem Gate Feedback eintragen → 💾 Feedback speichern". Bei aktivem Endpoint erscheint kein Fehler in der Konsole; in feedback-data/feedback.jsonl taucht eine neue Zeile auf. Ohne Endpoint: Header „⇩ Feedback" lädt die Backup-Datei.

Updates

  • Bei neuem Stand: git pull. Wenn sich App-Assets geändert haben, in sw.js die Konstante CACHE hochzählen (z. B. slc-companion-v1-v2), damit der Service Worker den Cache erneuert.

Noch offen (nicht Teil dieses Deploys)

  • YAML→Inhaltspipeline: Inhalte sind aktuell in index.html eingebettet. Später aus den Blueprint-service-lifecycle_*.yaml generieren (braucht Zugriff aufs Blueprint-Repo). Bis dahin werden Inhalte direkt in index.html gepflegt.
  • Companion-Chatbot (optionaler Nachschlage-Bot) — siehe ../README.md §8; braucht ein LLM-Backend und ist daher nicht Teil der statischen App.