From 6e2df33a9fc77b7be3759666abbf083e12f17768 Mon Sep 17 00:00:00 2001 From: Thomas Soring Date: Thu, 5 Mar 2026 21:34:27 +0100 Subject: [PATCH] docs: CI/CD-Pipeline-Guide mit verifiziertem Manual Git Webhook (HMAC) neu schreiben MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ersetzt Deploy-Webhook-Ansatz durch bewährten Manual Git Webhook mit HMAC-Secret. Basiert auf verifizierter Konfiguration: PATCH manual_webhook_secret_gitea in Coolify, Gitea Webhook via POST anlegen (nicht PATCH) – Secret wird nur beim Neuanlegen gespeichert. Co-Authored-By: Claude Sonnet 4.6 --- src/content/docs/guides/cicd-pipelines.md | 79 +++++++++++++---------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/src/content/docs/guides/cicd-pipelines.md b/src/content/docs/guides/cicd-pipelines.md index 689c9d2..2c73b02 100644 --- a/src/content/docs/guides/cicd-pipelines.md +++ b/src/content/docs/guides/cicd-pipelines.md @@ -7,52 +7,47 @@ sidebar: Der AI Application Layer unterstützt zwei Ansätze für automatische Deployments: -| Ansatz | Geeignet für | Komplexität | -|---|---|---| -| **Gitea Webhook → direkt deployen** | Einfache Projekte, schnelles Setup | Niedrig | -| **Gitea Actions / Pipeline** | Komplexere Workflows (Tests, Builds, Multi-Stage) | Mittel | +| Ansatz | Sicherheit | Komplexität | Empfohlen für | +|---|---|---|---| +| **Manual Git Webhook (HMAC)** | HMAC-signiert | Niedrig | Standard — alle Projekte | +| **Gitea Actions Pipeline** | Bearer Token in Secret | Mittel | Projekte mit Tests/Build-Schritten | --- -## Option 1: Direkt-Deployment via Webhook +## Option 1: Manual Git Webhook (empfohlen) -Der einfachste Weg: Gitea sendet bei jedem Push auf einen Branch automatisch einen Webhook an die Plattform, die daraufhin ein Deployment startet. +Gitea signiert jeden Webhook-Request mit einem gemeinsamen HMAC-Secret. Die Plattform prüft die Signatur — nur Requests mit korrekter Signatur lösen ein Deployment aus. -### Webhook-URL ermitteln - -Jede Anwendung auf der Plattform hat eine dedizierte Webhook-URL. Ihr findet sie in der Anwendungsübersicht unter **"Webhooks"** oder über die API: +### Schritt 1: Secret generieren ```bash -curl -s https://coolai.btc-ag.cloud/api/v1/applications/ \ - -H "Authorization: Bearer $COOLIFY_TOKEN" \ - | jq '{webhook: .manual_webhook_secret_gitea}' +openssl rand -hex 32 +# Beispiel-Output: af08f79869319d5cfe3ff6044dfd7115982b7db49685e635e1bc3875a3a26672 ``` -### Webhook in Gitea einrichten +### Schritt 2: Secret in der Plattform setzen -1. Repository in Gitea öffnen: `https://git.coolai.btc-ag.cloud` -2. **Settings → Webhooks → Webhook hinzufügen → Gitea** +```bash +curl -s -X PATCH https://coolai.btc-ag.cloud/api/v1/applications/ \ + -H "Authorization: Bearer $COOLIFY_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"manual_webhook_secret_gitea": ""}' +``` -| Feld | Wert | -|---|---| -| Ziel-URL | `https://coolai.btc-ag.cloud/api/v1/deploy?uuid=&force=false` | -| HTTP-Methode | `POST` | -| Content Type | `application/json` | -| Authorization-Header | `Bearer ` | -| Trigger | `Push Events` | -| Branch-Filter | z. B. `main` | +:::note +Das Secret wird gespeichert, aber aus Sicherheitsgründen nicht in der GET-Response zurückgegeben (`null`). Das ist korrekt — das Secret ist intern hinterlegt. +::: -3. **"Webhook testen"** — bei Erfolg erscheint im Anwendungs-Dashboard ein neues Deployment. +### Schritt 3: Gitea Webhook anlegen -### Webhook via Gitea API einrichten +Immer **POST** verwenden (nicht PATCH) — nur so wird das Secret korrekt gespeichert. ```bash GITEA_TOKEN="" GITEA_URL="https://git.coolai.btc-ag.cloud" REPO_OWNER="meinteam" REPO_NAME="meine-app" -APP_UUID="" -COOLIFY_TOKEN="" +SECRET="" curl -s -X POST "$GITEA_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/hooks" \ -H "Authorization: token $GITEA_TOKEN" \ @@ -60,20 +55,37 @@ curl -s -X POST "$GITEA_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/hooks" \ -d "{ \"type\": \"gitea\", \"config\": { - \"url\": \"https://coolai.btc-ag.cloud/api/v1/deploy?uuid=$APP_UUID&force=false\", + \"url\": \"https://coolai.btc-ag.cloud/webhooks/source/gitea/events/manual\", \"content_type\": \"json\", - \"authorization_header\": \"Bearer $COOLIFY_TOKEN\" + \"secret\": \"$SECRET\" }, \"events\": [\"push\"], + \"branch_filter\": \"main\", \"active\": true }" ``` +:::caution +`secret` wird in der API-Response und in der Gitea-UI nicht im Klartext angezeigt — das ist normal und kein Fehler. Das Secret ist intern korrekt gespeichert. + +Wichtig: Webhook immer via **POST** anlegen, nicht via PATCH eines bestehenden Hooks. Nur beim Neuanlegen wird das Secret zuverlässig übernommen. Wenn ein bestehender Webhook kein Secret hat: löschen und neu anlegen. +::: + +### Prüfen ob der Webhook funktioniert + +Nach dem nächsten `git push` auf `main` sollte im Dashboard ein neues Deployment erscheinen mit `is_webhook: true`: + +```bash +curl -s "https://coolai.btc-ag.cloud/api/v1/deployments/applications/" \ + -H "Authorization: Bearer $COOLIFY_TOKEN" \ + | jq '.deployments[0] | {status, is_webhook, created_at}' +``` + --- ## Option 2: Gitea Actions Pipeline -Für Projekte, die vor dem Deployment Tests, Linting oder komplexere Build-Schritte benötigen, empfiehlt sich eine Gitea Actions Pipeline. +Für Projekte, die vor dem Deployment Tests, Linting oder komplexere Build-Schritte benötigen. ### Beispiel: Node.js App mit Tests @@ -111,7 +123,7 @@ jobs: steps: - name: Deployment auslösen run: | - curl -s -X POST \ + curl -s -X GET \ "https://coolai.btc-ag.cloud/api/v1/deploy?uuid=${{ secrets.APP_UUID }}&force=false" \ -H "Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}" ``` @@ -147,11 +159,10 @@ Richtet dafür je eine Anwendung (mit eigener Domain und eigenem Webhook) pro Um ## Deployment-Status prüfen -Nach einem Trigger könnt ihr den aktuellen Status abfragen: +Nach einem Webhook-Trigger den aktuellen Status abfragen: ```bash -# Letztes Deployment einer Anwendung curl -s "https://coolai.btc-ag.cloud/api/v1/deployments/applications/" \ -H "Authorization: Bearer $COOLIFY_TOKEN" \ - | jq 'first | {status: .status, started: .created_at}' + | jq '.deployments[0] | {status, is_webhook, created_at}' ```