presseportale/dev/git-deploy-monitoring/README.md
Kevin Adametz 32e1349517 dev: Baukasten Git-Deploy und Betriebsüberwachung für andere Laravel-Projekte (dev/git-deploy-monitoring) — Anleitungen, Checkliste, Vorlagen für Laravel, deploy.sh und Monitoring-Server
Vorlagen in einem frischen Laravel 12 eingebaut (30 Tests grün), deploy.sh
gegen ein simuliertes Repository durchgespielt (Deploy, Abbruch bei
Migrationen, Drift, Rollback, fehlender Worker). GlitchTip-Aufbewahrung heißt
seit Version 6 GLITCHTIP_RETENTION_DAYS — in der Projekt-Doku korrigiert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 09:45:16 +00:00

121 lines
7.7 KiB
Markdown

# Git-Deploy und Betriebsüberwachung — Baukasten für Laravel-Projekte
**Stand:** 07.10.2026 · **Herkunft:** Pressekonto, live seit v1.1.3 (Git-Deploy) bzw. v1.1.0 (Monitoring)
**Für:** Entwickler und KI-Chats, die dieses Setup in ein anderes Laravel-Projekt übernehmen.
Dieser Ordner beschreibt ein erprobtes Betriebs-Setup aus zwei Teilen und liefert
die Dateien dafür mit:
1. **Git-Deploy per Tag** — ausgeliefert wird nur ein Git-Tag, von Hand per SSH,
mit einem Skript, das abbricht, bevor es etwas kaputt macht.
2. **Betriebsüberwachung** — Fehler, Ausfälle und stehende Hintergrundprozesse
fallen auf, bevor Kunden sie melden: GlitchTip (Fehlerprotokoll), `/health`
(tiefer Health-Check), Uptime Kuma (externer Monitor), ntfy (Push aufs Handy).
Die Laravel-Vorlagen sind in einem frischen Laravel 12 (12.69, PHP 8.4, Pest 3)
eingebaut und getestet (30 Tests grün); `deploy.sh` ist gegen ein simuliertes
Repository durchgespielt (Deploy, Abbruch bei Migrationen, Drift, Rollback,
fehlender Worker).
---
## Inhalt
| Datei | Wofür |
|---|---|
| [`01-git-deploy.md`](01-git-deploy.md) | Prinzip, einmalige Einrichtung, Release, Deploy, Rollback, Fallstricke |
| [`02-fehlerprotokoll-glitchtip.md`](02-fehlerprotokoll-glitchtip.md) | GlitchTip aufsetzen, Laravel anbinden (Server + Browser), Datenschutz, Auswertung per API |
| [`03-betriebsueberwachung.md`](03-betriebsueberwachung.md) | `/health`, Scheduler-Herzschlag, Worker-Prüfung, Alarme (Mail + ntfy), Uptime Kuma |
| [`04-checkliste-neues-projekt.md`](04-checkliste-neues-projekt.md) | Abhakliste für die Übernahme in ein neues Projekt |
| `vorlagen/deploy.sh` | Deploy-Skript (Einstellungen oben im Skript) |
| `vorlagen/env-beispiel.env` | alle `.env`-Werte mit Kommentar |
| `vorlagen/laravel/…` | PHP/JS/Blade-Dateien und Tests, Pfade wie im Projekt — 1:1 kopierbar |
| `vorlagen/server/…` | Docker-Compose für GlitchTip, ntfy, Uptime Kuma; ntfy-Konfiguration; Caddyfile |
---
## Architektur
```
┌────────────────────────── Monitoring-Server ──────────────────────────┐
│ GlitchTip (errors.…) ntfy (push.…) Uptime Kuma (status.…) │
└─────▲──────────────────────▲──────────────────────┬────────────────────┘
Fehler (Sentry-SDK) │ Betriebs-Alerts │ prüft jede │ Minute
│ (JSON-POST) │ /health, /up │
┌─────────────────────┴──────────────────────┴──────────────────────▼────────────────────┐
│ App-Server: Laravel │
│ • Exceptions + Fehlersignale → GlitchTip • Scheduler schreibt Herzschlag/Minute │
│ • fehlgeschlagene Jobs/Tasks → Mail + ntfy • /health: DB, Cache, Queue, Scheduler, │
│ • deploy.sh: Tag auschecken, Worker prüfen Platte → 200 / 503 │
└─────────────────────▲───────────────────────────────────────────────────────────────────┘
│ git fetch --tags (Deploy-Key, nur lesen)
┌────────┴────────┐
│ Git-Server │ ← lokal: Commit, Assets bauen, Tag, push
│ (Forgejo o. Ä.) │
└─────────────────┘
```
**Wichtig:** Uptime Kuma läuft auf einem anderen Server als die App — sonst fällt
der Monitor mit dem überwachten System aus. ntfy liegt auf demselben Server wie
Uptime Kuma; fällt dieser aus, kommt kein Push. Dafür gibt es eine zweite Ebene
(kostenloser externer Dienst, nur Mail), siehe 03.
### Wer meldet was?
| Ausfall | Wer merkt es | Kanal |
|---|---|---|
| Exception im Code (Request, Job, Command) | Sentry-SDK | GlitchTip → Mail bei neuem Fehlertyp |
| JavaScript-Fehler im Browser | `error-reporting.js` | GlitchTip (Projekt Browser) |
| Toter interner Link, 403/429 für Angemeldete, 419 | `ReportErrorSignals` | GlitchTip (Warnung) |
| Job endgültig fehlgeschlagen | `Queue::failing` | Mail + ntfy |
| Geplanter Task fehlgeschlagen | `onFailure` | Mail + ntfy |
| Worker steht | `/health` (Queue-Rückstau) | Uptime Kuma → ntfy/Mail |
| Scheduler/Cron steht | `/health` (Herzschlag) | Uptime Kuma |
| Platte fast voll, DB/Cache weg | `/health` | Uptime Kuma |
| Server/PHP-FPM/Nginx/SSL weg | `/up`, `/health` nicht erreichbar | Uptime Kuma (+ zweite Ebene) |
| Worker kommt nach dem Deploy nicht zurück | `deploy.sh` (Test-Job) | Exit 3 im Terminal |
---
## Reihenfolge für ein neues Projekt
1. **Monitoring-Server** einmalig aufsetzen (GlitchTip, ntfy, Uptime Kuma) — wird
von allen Projekten geteilt. Je Projekt nur neue GlitchTip-Projekte, ein
ntfy-Topic und Monitore.
2. **Laravel-Teil** einbauen (02, 03), Tests grün, ausliefern.
3. **Git-Deploy** einrichten (01) — für ein bestehendes Live-Verzeichnis mit der
Umwandlung an Ort und Stelle.
4. **Uptime Kuma** auf `/health` richten, Alarm testen.
Die Abhakliste dazu: [`04-checkliste-neues-projekt.md`](04-checkliste-neues-projekt.md).
---
## Bewusst nicht im Baukasten
- **Zero-Downtime mit Release-Verzeichnissen** (Envoyer/Deployer-Stil): Wer
große Dateien unter `storage/app` hält, deployt besser im selben Verzeichnis
mit `artisan down` (wenige Sekunden).
- **Admin-Systemstatus-Seite**: projektspezifisch. `HealthProbe::scheduler()`
und `disk()` lassen sich dort mitbenutzen.
- **Webanalyse (Umami)** und **Auswertung fehlgeschlagener Logins**: in
Pressekonto vorhanden, aber eng mit dem Projekt verwoben. Muster in 03,
Abschnitt „Erweiterungen“.
---
## Erfahrungen aus dem Betrieb (warum es so gebaut ist)
| Erfahrung | Folge im Baukasten |
|---|---|
| Die Testsuite meldete absichtlich provozierte Fehler („Queue weg“) an das echte GlitchTip | DSNs in `phpunit.xml` leer, Wächtertest |
| GlitchTip gruppiert nach Text — `…after 20002 ms` und `…20001 ms` wurden getrennte Einträge | keine variablen Zahlen in Meldungen; Fingerprint bei Signalen |
| Ein Google-Aussetzer erzeugte 28 Fehlermeldungen in einer Nacht | vorübergehende Fremdfehler: Retry, `Log::warning`, Alarm erst bei Abbruch |
| Nach `queue:restart` kam der Worker nicht zurück — Supervisor lief nicht. Eine Stunde blieben Jobs liegen | Worker-Prüfung am Ende von `deploy.sh`, `/health` prüft den Rückstau |
| FPM per „Restart“ statt „Reload“ → Socket kurz weg → 502 | `deploy.sh` macht `reload`; Restart nie |
| Version auf Live zeigte `v1.1.0-3-g…-dirty` | `deploy.sh` schreibt `RELEASE` = Tag selbst |
| macOS-Muster `Icon` in `.gitignore` traf bei `core.ignorecase` auch `resources/views/flux/icon/` | bei der Umstellung `git status` auf Live genau sichten (01, Fallstricke) |
| Per SFTP gelöschte Dateien lagen noch auf Live | Umwandlung zeigt Abweichungen, bevor ausgecheckt wird |
| `deploy.sh` wird beim Checkout ersetzt, während Bash es liest | Skript läuft aus einer Kopie |
| Alte fehlgeschlagene Jobs scheiterten nach `queue:retry all` an geänderten Klassen | nie pauschal `retry all`; `queue:prune-failed` nach 30 Tagen |
| `:placeholder="__('…')"` an `<input>` → Alpine-Fehler im Browser, nur durch GlitchTip gefunden | Browserfehler erfassen; Muster mit Wächtertest abfangen |