# Auto-Update auf einem Produktionsserver Dieses Dokument beschreibt, wie ein bereits laufendes `monitor` auf einem Produktionsserver sich selbst aktualisiert, sobald der Repo-Besitzer einen Pull Request nach `main` mergt. Anders als im parallelen [Agent-Projekt](https://codeberg.org/fds2610/Agent) gibt es hier **keine** Trennung zwischen einem unveraenderlichen "Bootstrap"-Updater und dem eigentlichen Projekt-Code - `update.sh` gehoert direkt zum Projekt und wird bei jedem Update mit aktualisiert. ## Bausteine - **`update.sh`** (Projekt-Wurzel) - holt die neueste Version des konfigurierten Branches per `git pull --ff-only`, baut die Docker-Images neu, startet `api`, `web` und `sync` neu und fuehrt (per Default) die Testsuiten aus. Kann jederzeit auch manuell aufgerufen werden, siehe Kommentar am Kopf der Datei fuer die Umgebungsvariablen `UPDATE_REMOTE`, `UPDATE_BRANCH`, `UPDATE_RUN_TESTS`. - **`deploy-webhook.py`** (Projekt-Wurzel) - kleiner HTTP-Server (nur Python-Standardbibliothek, keine Abhaengigkeiten) auf Basis von `http.server`. Prueft eingehende Codeberg-Webhooks per HMAC-Signatur (`X-Forgejo-Signature`/`X-Gitea-Signature`, analog zum bestehenden `POST /api/v1/webhooks/codeberg` aus [API.md](API.md)) und ruft bei einem Push auf den konfigurierten Branch `update.sh` auf. Laeuft **auf dem Host**, nicht im Docker-Compose-Stack - `update.sh` selbst ruft `docker compose` auf dem Host auf, das waere aus einem Container heraus nur mit riskantem Zugriff auf den Docker-Socket moeglich. - **`deploy/monitor-deploy-webhook.service`** - systemd-Unit-Vorlage, um `deploy-webhook.py` dauerhaft im Hintergrund laufen zu lassen. ## Manuelle Vorarbeiten auf dem Server Diese Schritte sind einmalig und **nicht** Teil dieses Repos (unterschiedlich je nach Server), daher hier nur als Checkliste: 1. **Repo auskecken.** `git clone https://codeberg.org/fds2610/monitor.git` (oder per SSH, falls Push-Zugangsdaten fuer `git pull` als Deploy-Key/SSH-Key eingerichtet werden) nach z.B. `/opt/monitor`, Branch `main` ausgecheckt. Versionierte Dateien duerfen dort nicht lokal veraendert werden - `update.sh` bricht kontrolliert ab, statt die Aenderungen zu ueberschreiben (Notausgang: `UPDATE_ALLOW_DIRTY=1`). Unversionierte Dateien neben dem Repo (`.env`, `hosts.conf`, `monitor-api.conf`, `credentials.conf`) stoeren dagegen nicht, sie bleiben beim Update unangetastet. 2. **Docker + Docker Compose** installieren (`docker compose version` muss funktionieren). Der Benutzer, unter dem `deploy-webhook.py` laeuft, braucht Mitgliedschaft in der `docker`-Gruppe (oder aequivalente Rechte), um `docker compose` ohne `sudo` aufzurufen. 3. **Python 3** installieren (Standardbibliothek genuegt, keine weiteren Pakete noetig) - `mail_fds.py` im selben Repo setzt das ohnehin schon voraus. 4. **`.env` anlegen** aus `.env.example`, insbesondere `MONITOR_ADMIN_API_KEY`, `MONITOR_API_BASE` und die neuen Variablen `MONITOR_DEPLOY_WEBHOOK_SECRET`, `MONITOR_DEPLOY_WEBHOOK_PORT`, `MONITOR_DEPLOY_WEBHOOK_BRANCH` (Details siehe dort). Das Secret z.B. mit `openssl rand -hex 32` erzeugen. 5. **systemd-Unit einrichten:** ```bash sudo cp deploy/monitor-deploy-webhook.service /etc/systemd/system/ sudo $EDITOR /etc/systemd/system/monitor-deploy-webhook.service # Pfade/User/Group anpassen sudo systemctl daemon-reload sudo systemctl enable --now monitor-deploy-webhook sudo systemctl status monitor-deploy-webhook ``` 6. **Port/Proxy freischalten.** `deploy-webhook.py` lauscht auf `MONITOR_DEPLOY_WEBHOOK_PORT` (Default `9099`) auf allen Interfaces. Analog zum bestehenden Codeberg-Sync-Webhook muss Proxy/Firewall eingehende Anfragen von Codeberg an diesen Port (bzw. an einen dahinter liegenden Reverse-Proxy-Pfad) durchlassen - alle anderen Dienste (`api`, `web`, `sync`) brauchen dafuer keine Aenderung. 7. **Webhook in Codeberg einrichten** (macht der Repo-Besitzer manuell, siehe Issue #36): Repo-Einstellungen -> Webhooks -> Forgejo, Ziel-URL auf `deploy-webhook.py` (Port aus Schritt 6, ggf. per Proxy auf `https://...` gemappt), Content-Type `application/json`, Secret wie in `.env` (`MONITOR_DEPLOY_WEBHOOK_SECRET`), Ereignis **nur** "Push". Ein Merge erzeugt immer einen Push auf den Ziel-Branch, ein eigenes "Pull Request merged"-Event ist daher nicht noetig. ## Testen Zustellung testen (Codeberg schickt beim Anlegen automatisch ein `ping`-Event, sichtbar unter "Letzte Zustellungen" im Webhook selbst). Manuell mit korrekter Signatur: ```bash SECRET= BODY='{"ref":"refs/heads/main"}' SIG=$(python3 -c "import hmac,hashlib,sys; print(hmac.new(sys.argv[1].encode(), sys.argv[2].encode(), hashlib.sha256).hexdigest())" "$SECRET" "$BODY") curl -i -X POST "http://:9099/" \ -H "X-Forgejo-Event: push" \ -H "X-Forgejo-Signature: $SIG" \ -d "$BODY" ``` Antwort `202 {"status": "update gestartet"}` bedeutet, dass `update.sh` im Hintergrund laeuft. Der Verlauf landet in `MONITOR_DEPLOY_LOG_FILE` (Default: `deploy-webhook.log` neben `deploy-webhook.py`) sowie im systemd-Journal (`journalctl -u monitor-deploy-webhook -f`). ## Sicherheit Der Endpunkt ist wie `POST /api/v1/webhooks/codeberg` ohne Secret grundsaetzlich geschlossen (401) und akzeptiert nur Anfragen mit gueltiger HMAC-Signatur. Er loest im Erfolgsfall lediglich denselben `git pull --ff-only` + Rebuild aus, den ein Server-Betreiber auch manuell per `./update.sh` anstossen wuerde - er bringt also keinen Code auf den Server, der nicht bereits reviewt und **manuell** nach `main` gemergt wurde. Diese manuelle Merge-Hürde ist laut Repo-Besitzer (Issue #36) als alleinige Sicherheitsmassnahme ausreichend; zusaetzliche Branch-Protection-Einstellungen im Codeberg-Repo (z.B. kein direkter Push nach `main`) bleiben trotzdem empfehlenswert, sind aber eine manuelle Repo-Einstellung und nicht Teil dieses Skripts.