Goldene Regel: Erstellen Sie vor jedem Upgrade ein Datenbank-Backup. Datenbankmigrationen werden beim Start automatisch ausgeführt und sind möglicherweise nicht rückgängig zu machen.
Überblick
Versionsschema
Reva folgt Semantic Versioning:
- Major (X.0.0) — Breaking Changes, manuelle Migrationsschritte erforderlich
- Minor (1.X.0) — neue Funktionen, abwärtskompatibel
- Patch (1.0.X) — Fehlerbehebungen und Sicherheitspatches
Komponentenversionen
Ein Reva-Deployment besteht aus mehreren unabhängig versionierten Komponenten:
| Komponente | Versionsquelle | Beispiel |
|---|---|---|
| Reva-Anwendung | REVA_VERSION in .env / Image-Tag | 1.0.4 |
| Release-MCP-Sidecar | Image-Tag in docker-compose oder K8s-Manifest | 25.3.0-beta.926 |
| Jira-MCP-Sidecar | Image-Tag in docker-compose oder K8s-Manifest | 0.21.0 |
| PostgreSQL | Basis-Image-Tag | pg16 |
| Redis | Basis-Image-Tag | 7-alpine |
| Ollama-Modelle | Modell-Tag auf dem Ollama-Server | qwen3:14b |
Upgrade-Philosophie
- Lesen Sie das CHANGELOG vor jedem Upgrade
- Erstellen Sie ein Datenbank-Backup
- Prüfen Sie, ob das aktuelle Deployment gesund ist
- Aktualisieren Sie eine Komponente nach der anderen, wenn möglich
- Prüfen Sie den Gesundheitszustand nach jeder Änderung
- Wissen Sie, wie Sie zurückrollen können, bevor Sie beginnen
Checkliste vor dem Upgrade
Gehen Sie diese Checkliste vor jedem Upgrade durch, unabhängig von der Deployment-Methode.
Aktuelle Version notieren
docker inspect reva --format '{{.Config.Image}}'
kubectl get deployment reva -n reva -o jsonpath='{.spec.template.spec.containers[0].image}'
Aktuellen Zustand prüfen
curl -s http://localhost:3978/api/health | python3 -m json.tool
kubectl exec -n reva deploy/reva -c reva -- \
python -c "import urllib.request; print(urllib.request.urlopen('http://localhost:8000/api/health').read().decode())"
Die erwartete Ausgabe enthält "status": "ok" und alle MCP-Server zeigen "connected": true.
Datenbank-Backup erstellen
./bin/backup-db.sh
Erstellt ein komprimiertes Backup unter backups/reva_YYYY-MM-DD_HHMMSS.sql.gz mit 30-Tage-Aufbewahrung.
# Manuelles Backup auslösen
kubectl create job --from=cronjob/db-backup manual-backup-pre-upgrade -n reva
# Auf Abschluss warten
kubectl wait --for=condition=complete job/manual-backup-pre-upgrade -n reva --timeout=120s
# Erfolg prüfen
kubectl logs job/manual-backup-pre-upgrade -n reva
CHANGELOG lesen
cat CHANGELOG.md
Achten Sie auf:
- Breaking Changes in Major-/Minor-Releases
- Explizit genannte Migrationsschritte
- Änderungen an Umgebungsvariablen oder Secret-Namen
- MCP-Sidecar-Versionsaktualisierungen, die Konfigurationsanpassungen erfordern könnten
Docker-Compose-Upgrade
1 CHANGELOG lesen
cat CHANGELOG.md
Achten Sie auf Breaking Changes zwischen Ihrer aktuellen und der Zielversion.
2 Datenbank-Backup erstellen
./bin/backup-db.sh
# Prüfen, ob das Backup erstellt wurde
ls -lh backups/reva_*.sql.gz | tail -1
3 Version aktualisieren
REVA_VERSION in .env bearbeiten:
# Beispiel: Upgrade von 1.0.4 auf 1.0.5
sed -i.bak 's/^REVA_VERSION=.*/REVA_VERSION=1.0.5/' .env
Die docker-compose.yml referenziert diese Variable:
image: ghcr.io/x-idra-systems-gmbh/reva:${REVA_VERSION:-latest}
4 Neue Images laden
docker compose pull
Damit wird das neue Reva-Image von ghcr.io geladen. Wenn Sie auch MCP-Sidecar-Versionen in docker-compose.yml aktualisiert haben, werden diese Images ebenfalls geladen.
5 Dienste neustarten
docker compose up -d
Docker Compose erstellt nur die Container neu, deren Images sich geändert haben. Die depends_on-Konfiguration stellt sicher, dass PostgreSQL und Redis gesund sind, bevor Reva startet.
6 Gesundheitszustand prüfen
curl -s http://localhost:3978/api/health | python3 -m json.tool
Bestätigen Sie:
"status": "ok""db": true"adapter_initialized": true- Beide MCP-Server zeigen
"connected": true
7 Logs auf Migrationsausgaben prüfen
# Alembic-Migrationsausgaben prüfen
docker compose logs reva | grep -i -E "(alembic|migration|upgrade)"
# Auf Fehler prüfen
docker compose logs reva | grep -i error | tail -20
# Logs live verfolgen
docker compose logs -f reva
Kubernetes-Kustomize-Upgrade
1 CHANGELOG lesen
cat CHANGELOG.md
2 Datenbank-Backup erstellen
kubectl create job --from=cronjob/db-backup manual-backup-pre-upgrade -n reva
kubectl wait --for=condition=complete job/manual-backup-pre-upgrade -n reva --timeout=120s
kubectl logs job/manual-backup-pre-upgrade -n reva
3 Image-Tags aktualisieren
Bearbeiten Sie k8s/reva-deployment.yaml, um den neuen Image-Tag für den Reva-Container zu setzen.
Bei lokalem Build für k3s:
# Neues Image bauen
docker build -t reva:<neue-version> .
# In k3s importieren
docker save reva:<neue-version> | sudo k3s ctr images import -
Bei Pull von ghcr.io:
docker pull ghcr.io/x-idra-systems-gmbh/reva:<neue-version>
docker tag ghcr.io/x-idra-systems-gmbh/reva:<neue-version> reva:<neue-version>
docker save reva:<neue-version> | sudo k3s ctr images import -
4 Manifeste anwenden
kubectl apply -k k8s/
5 Rollout beobachten
kubectl rollout status deployment/reva -n reva --timeout=120s
Dieser Befehl wartet, bis der neue Pod bereit ist oder das Timeout erreicht wird.
6 Gesundheitszustand prüfen
# Port-Forwarding und Prüfung
kubectl port-forward -n reva svc/reva 8000:8000 &
curl -s http://localhost:8000/api/health | python3 -m json.tool
kill %1
# Oder direkt im Pod
kubectl exec -n reva deploy/reva -c reva -- \
python -c "import urllib.request; print(urllib.request.urlopen('http://localhost:8000/api/health').read().decode())"
7 Logs prüfen
kubectl logs -n reva deploy/reva -c reva | grep -i -E "(alembic|migration|upgrade)"
kubectl logs -n reva deploy/reva -c reva | grep -i error | tail -20
Kubernetes-Helm-Upgrade
1 CHANGELOG lesen
cat CHANGELOG.md
2 Datenbank-Backup erstellen
kubectl create job --from=cronjob/db-backup manual-backup-pre-upgrade -n reva
kubectl wait --for=condition=complete job/manual-backup-pre-upgrade -n reva --timeout=120s
kubectl logs job/manual-backup-pre-upgrade -n reva
3 Version aktualisieren
Option A — values.yaml bearbeiten:
# values.yaml
reva:
image:
tag: "1.0.5"
Option B — Version auf der Kommandozeile übergeben:
helm upgrade reva helm/reva/ -n reva --set reva.image.tag=1.0.5
4 Upgrade durchführen
# Mit Values-Datei
helm upgrade reva helm/reva/ -n reva -f values.yaml
# Oder mit --set
helm upgrade reva helm/reva/ -n reva --set reva.image.tag=1.0.5
5 Rollout prüfen
# Helm-Release-Status prüfen
helm status reva -n reva
# Pod-Rollout beobachten
kubectl rollout status deployment/reva -n reva --timeout=120s
# Gesundheitszustand prüfen
kubectl exec -n reva deploy/reva -c reva -- \
python -c "import urllib.request; print(urllib.request.urlopen('http://localhost:8000/api/health').read().decode())"
6 Logs prüfen
kubectl logs -n reva deploy/reva -c reva | grep -i -E "(alembic|migration|upgrade)"
kubectl logs -n reva deploy/reva -c reva | grep -i error | tail -20
Rollback-Verfahren
# Auf vorherige Version zurücksetzen
sed -i.bak 's/^REVA_VERSION=.*/REVA_VERSION=1.0.4/' .env
# Mit dem alten Image neustarten
docker compose up -d
# Prüfen
curl -s http://localhost:3978/api/health | python3 -m json.tool
# Auf vorherige Revision zurückrollen
kubectl rollout undo deployment/reva -n reva
# Prüfen
kubectl rollout status deployment/reva -n reva --timeout=120s
Aktualisieren Sie anschließend k8s/reva-deployment.yaml mit dem zurückgesetzten Image-Tag, damit das nächste kubectl apply -k k8s/ nicht die fehlerhafte Version erneut anwendet.
# Release-Verlauf anzeigen
helm history reva -n reva
# Auf vorherige Revision zurückrollen
helm rollback reva -n reva
# Oder auf eine bestimmte Revision zurückrollen
helm rollback reva 3 -n reva
# Prüfen
helm status reva -n reva
kubectl rollout status deployment/reva -n reva --timeout=120s
Datenbank-Rollback
Wenn eine Migration Daten oder das Schema beschädigt hat, stellen Sie das Backup von vor dem Upgrade wieder her.
# Reva stoppen (Postgres weiterlaufen lassen)
docker compose stop reva
# Aus Backup wiederherstellen
gunzip -c backups/reva_2026-03-15_020000.sql.gz | \
docker exec -i reva-postgres psql -U postgres -d reva
# REVA_VERSION in .env auf vorherige Version zurücksetzen
sed -i.bak 's/^REVA_VERSION=.*/REVA_VERSION=1.0.4/' .env
# Mit der alten Version neustarten
docker compose up -d
# Reva herunterskalieren, um Schreibzugriffe zu stoppen
kubectl scale deployment/reva -n reva --replicas=0
# Aus Backup mit einem temporären Pod wiederherstellen
kubectl run pg-restore -n reva --rm -it \
--image=pgvector/pgvector:pg16 \
--env="PGPASSWORD=<admin-passwort>" \
-- sh -c 'gunzip -c /backups/reva_<ZEITSTEMPEL>.sql.gz | psql -h postgres -U postgres -d reva'
# Image-Tag in Manifesten zurücksetzen, dann erneut anwenden
kubectl apply -k k8s/
# Oder: helm rollback reva -n reva
# Wieder hochskalieren
kubectl scale deployment/reva -n reva --replicas=1
Warnung: Datenbank-Rollbacks stellen Daten auf den Backup-Zeitpunkt wieder her. Alle Daten, die zwischen dem Backup und dem Rollback geschrieben wurden, gehen verloren.
Datenbankmigrationen
Reva verwendet zwei Migrationsmechanismen, die beide beim Start automatisch ausgeführt werden — bei normalen Upgrades ist kein manueller Eingriff erforderlich.
Alembic-Migrationen (Renfield-Plattform)
Die Renfield-Plattform verwaltet ihr Schema über Alembic. Migrationen werden beim Anwendungsstart automatisch ausgeführt. Die Ausgabe sieht so aus:
INFO [alembic.runtime.migration] Running upgrade abc123 -> def456, add memory table
SQLAlchemy metadata.create_all() (Reva-Tabellen)
Reva-spezifische Tabellen werden über SQLAlchemy's metadata.create_all() erstellt, was idempotent ist. Neue Tabellen werden erstellt, wenn sie noch nicht existieren, bestehende Tabellen bleiben unberührt.
Was tun, wenn eine Migration fehlschlägt?
1 Logs prüfen auf den konkreten Fehler:
docker compose logs reva | grep -i -E "(alembic|error|traceback)" | tail -40
kubectl logs -n reva deploy/reva -c reva | grep -i -E "(alembic|error|traceback)" | tail -40
2 Häufige Ursachen:
- Lock-Konflikte: Ein anderer Prozess hält eine Sperre auf der Datenbank. Stellen Sie sicher, dass während des Upgrades nur eine Reva-Instanz läuft (
replicas: 1,strategy: Recreate). - Schema-Drift: Manuelle DDL-Änderungen stehen im Konflikt mit Alembics erwartetem Zustand. Vergleichen Sie das aktuelle Schema mit Alembics Erwartungen.
- Speicherplatz: Das Datenbank-Volume ist voll. Prüfen Sie mit
df -him Postgres-Container.
3 Wiederherstellung: Wenn die Migration fehlschlägt, startet die Anwendung nicht und der Health Check schlägt fehl. Rollen Sie auf die vorherige Version zurück (siehe Rollback-Verfahren) und melden Sie den Migrationsfehler.
MCP-Server-Updates
Die Release-MCP- und Jira-MCP-Sidecars sind unabhängig versioniert. Sie können sie aktualisieren, ohne die Reva-Anwendungsversion zu ändern.
MCP-Container laufen über Docker-in-Docker (konfiguriert in config/mcp_servers.yaml). Aktualisieren Sie dort die Image-Tags:
vi config/mcp_servers.yaml
# Image-Tag für release-mcp oder jira-mcp aktualisieren
Dann Reva neustarten, damit die MCP-Container neu erstellt werden:
docker compose restart reva
Bearbeiten Sie k8s/reva-deployment.yaml und aktualisieren Sie die Sidecar-Image-Tags:
# Release-MCP-Sidecar
- name: release-mcp
image: xebialabsearlyaccess/dai-release-mcp:25.3.0-beta.NEUER_TAG
# Jira-MCP-Sidecar
- name: jira-mcp
image: ghcr.io/sooperset/mcp-atlassian:0.NEUER_TAG
Änderung anwenden:
kubectl apply -k k8s/
kubectl rollout status deployment/reva -n reva --timeout=120s
Sidecar-Image-Tags in values.yaml aktualisieren:
mcp:
release:
image:
tag: "25.3.0-beta.NEUER_TAG"
jira:
image:
tag: "0.NEUER_TAG"
Dann upgraden:
helm upgrade reva helm/reva/ -n reva -f values.yaml
MCP-Konnektivität prüfen
Bestätigen Sie nach dem Update der MCP-Sidecars, dass sie sich wieder verbinden:
curl -s http://localhost:3978/api/health | python3 -m json.tool
kubectl exec -n reva deploy/reva -c reva -- \
python -c "import urllib.request; print(urllib.request.urlopen('http://localhost:8000/api/health').read().decode())"
Beide MCP-Server sollten "connected": true anzeigen.
Ollama-Modell-Updates
Reva nutzt Ollama für LLM-Inferenz. Das Agent-Modell (qwen3:14b) und das Router-Modell (llama3.2:3b) laufen auf dem Ollama-Server, der extern zum Reva-Deployment ist.
Neue Modellversion laden
# Auf dem Ollama-Server
ollama pull qwen3:14b
# Verfügbarkeit prüfen
ollama list | grep qwen3
Modell testen
ollama run qwen3:14b "Sage Hallo in einem Satz" --verbose
Modellreferenz aktualisieren
Wenn Sie auf ein völlig anderes Modell wechseln (nicht nur das gleiche Tag aktualisieren), ändern Sie die Agent-Rollenkonfiguration:
vi config/agent_roles.yaml
# Modell-Feld für jede Rolle aktualisieren
Dann Reva neustarten:
docker compose restart reva
kubectl rollout restart deployment/reva -n reva
Wichtig: Setzen Sie AGENT_MODEL nicht in .env — es überschreibt das Router-Modell. Agent-Modelle werden pro Rolle in config/agent_roles.yaml konfiguriert.
Version-Pinning
Reva pinnen
Pinnen Sie REVA_VERSION in .env immer auf eine bestimmte Version. Verwenden Sie in Produktion niemals latest:
# .env
REVA_VERSION=1.0.4
MCP-Sidecars pinnen
Verwenden Sie in k8s/reva-deployment.yaml oder values.yaml explizite Image-Tags:
# Gut
image: xebialabsearlyaccess/dai-release-mcp:25.3.0-beta.926
image: ghcr.io/sooperset/mcp-atlassian:0.21.0
# Schlecht -- nicht in Produktion verwenden
image: xebialabsearlyaccess/dai-release-mcp:latest
Infrastruktur pinnen
Pinnen Sie PostgreSQL- und Redis-Versionen:
# docker-compose.yml / K8s-Manifeste
image: pgvector/pgvector:pg16 # nicht pgvector/pgvector:latest
image: redis:7-alpine # nicht redis:latest
Eingesetzte Versionen dokumentieren
Dokumentieren Sie nach jedem Upgrade die eingesetzten Versionen für Audit und Rollback:
echo "=== Reva ===" && docker inspect reva --format '{{.Config.Image}}'
echo "=== Postgres ===" && docker inspect reva-postgres --format '{{.Config.Image}}'
echo "=== Redis ===" && docker inspect reva-redis --format '{{.Config.Image}}'
echo "=== Ollama-Modelle ===" && ollama list
Ein Versionsinventar erleichtert Rollbacks und hilft bei der Diagnose von Umgebungsunterschieden zwischen Staging und Produktion.
Fehlerbehebung
Health Check schlägt nach Upgrade fehl
Symptom: GET /api/health gibt 503 zurück oder läuft in ein Timeout.
# Prüfen, was fehlschlägt
curl -s http://localhost:3978/api/health | python3 -m json.tool
# Container-Status prüfen
docker compose ps
# Logs auf Startfehler prüfen
docker compose logs reva --tail 50
Häufige Ursachen:
- Datenbank nicht bereit: Reva startet bevor Postgres gesund ist. Warten Sie, bis die Readiness-Probe bestanden ist.
- Fehlende Umgebungsvariable: Eine neue Version erfordert möglicherweise eine neue Umgebungsvariable. Prüfen Sie das CHANGELOG auf neue Konfigurationsanforderungen.
- Fehlende Secret-Datei: Wenn ein neues Secret hinzugefügt wurde, generieren Sie es mit
./bin/generate-secrets.sh.
MCP-Server verbindet sich nicht
Symptom: Health Check zeigt "connected": false für einen oder beide MCP-Server.
docker logs reva-release-mcp 2>&1 | tail -20
docker logs reva-jira-mcp 2>&1 | tail -20
kubectl logs -n reva deploy/reva -c release-mcp --tail 20
kubectl logs -n reva deploy/reva -c jira-mcp --tail 20
Häufige Ursachen:
- MCP-Image nicht gefunden: Der Sidecar-Image-Tag existiert nicht. Prüfen Sie den Tag mit
docker pull <image>:<tag>. - Zugangsdaten stimmen nicht: Die Release- oder Jira-Zugangsdaten in den Secrets passen nicht zu den Anforderungen der neuen MCP-Version.
- Netzwerkproblem: Der MCP-Sidecar kann den Release- oder Jira-Server nicht erreichen. Prüfen Sie DNS-Auflösung und Firewall-Regeln.
Alembic-Migrationsfehler
Symptom: Reva startet nicht und zeigt einen Alembic-Fehler in den Logs.
docker compose logs reva | grep -A5 "alembic"
Häufige Ursachen:
- Gleichzeitige Migration: Zwei Reva-Instanzen haben gleichzeitig migriert. Stellen Sie sicher, dass während des Upgrades nur ein Replica läuft (
strategy: Recreate). - Manuelle Schemaänderung: Ein vorheriges manuelles
ALTER TABLEsteht im Konflikt mit Alembics Migrationsverlauf.
Lösung:
- Auf die vorherige Reva-Version zurückrollen
- Datenbank bei Bedarf aus Backup wiederherstellen
- Migrationsfehler mit angehängten Logs melden
Container kann Image nicht laden
Symptom: docker compose pull schlägt mit Authentifizierungsfehler fehl.
# ghcr.io-Login prüfen
docker login ghcr.io
# Prüfen, ob REVA_VERSION mit einem veröffentlichten Tag übereinstimmt
docker manifest inspect ghcr.io/x-idra-systems-gmbh/reva:1.0.5
Wenn Ihr GHCR-Token abgelaufen ist, generieren Sie ein neues Personal Access Token mit read:packages-Berechtigung und melden Sie sich erneut an:
echo $GHCR_TOKEN | docker login ghcr.io -u <benutzername> --password-stdin
Pod hängt in CrashLoopBackOff (Kubernetes)
Symptom: Der Reva-Pod startet immer wieder neu.
# Pod-Events prüfen
kubectl describe pod -n reva -l app.kubernetes.io/name=reva
# Logs des abgestürzten Containers prüfen
kubectl logs -n reva -l app.kubernetes.io/name=reva -c reva --previous
Häufige Ursachen:
- OOM killed: Der Container hat sein Speicherlimit überschritten. Prüfen Sie
kubectl describe podaufOOMKilled-Grund. Erhöhen Sieresources.limits.memory. - Start-Timeout: Die Liveness-Probe feuert bevor die App bereit ist. Erhöhen Sie
initialDelaySecondsoderfailureThresholdtemporär. - Konfigurationsfehler: Eine erforderliche Umgebungsvariable fehlt oder ist ungültig. Prüfen Sie die Logs auf Pydantic-
ValidationError.
Secrets nach Upgrade nicht verfügbar
Symptom: Reva-Logs zeigen Authentifizierungsfehler gegenüber Release, Jira oder der Datenbank.
# Secrets prüfen
ls -la secrets/
# Bei Bedarf neu generieren
./bin/generate-secrets.sh
# Secret prüfen
kubectl get secret reva-secrets -n reva -o jsonpath='{.data}' | python3 -m json.tool
# values.yaml mit neuen Secret-Werten aktualisieren, dann upgraden
helm upgrade reva helm/reva/ -n reva -f values.yaml