- dev/betrieb/deploy.sh: Tag auschecken, composer, Caches leeren (bewusst
kein route:/config:cache wegen hostabhaengiger Routen und env()-Aufrufen),
horizon:terminate, FPM-Reload, Worker-Pruefung am Ende
- dev/betrieb/README.md: Einrichtung Server, Umstellung des Live-Verzeichnisses,
Release, Deploy, Rollback
- config('app.version') aus RELEASE, php artisan about --only=mivita
- monitoring:queue-probe prueft nach dem Deploy, ob Horizon Jobs abholt
- Vorlage dev/git-deploy-monitoring aus Pressekonto
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
121 lines
7.7 KiB
Markdown
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 |
|