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>
124 lines
5.7 KiB
Markdown
124 lines
5.7 KiB
Markdown
# 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`](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.php` — **optionaler** 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
|
|
```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)
|
|
```caddy
|
|
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):
|
|
|
|
```bash
|
|
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
|
|
```
|
|
|
|
```nginx
|
|
# 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.
|