Skip to content

Upgrade

Zwei Binaries zum Upgraden: der Manager (docker-compose-Stack) und Edges (eine pro Host). Beide folgen demselben konzeptionellen Fluss: die neuen Artefakte lagern, atomar einwechseln, automatisch auf die vorherige Version zurückfallen, wenn die neue nicht gesund hochkommt.

TL;DR

Manager:

bash
VER=v0.7.160
gh release download "$VER" --repo ongridio/ongrid \
    -p 'ongrid-*-linux-amd64.tar.xz*'
sha256sum -c "ongrid-${VER}-linux-amd64.tar.xz.sha256"
tar xf "ongrid-${VER}-linux-amd64.tar.xz"
cd     "ongrid-${VER}-linux-amd64"
sudo ./upgrade.sh

Edges (alle, parallel, aus der UI):

  • Edges → Upgrade all — der Manager pusht MethodFetchPackage an jede verbundene Edge, jede lädt das gelagerte Bundle von https://<manager>/edge/ herunter, lagert es, startet neu, wechselt, läuft. Fehlschläge auto-rollback beim nächsten Boot.

Oder für eine einzelne Edge aus der Shell:

bash
sudo systemctl restart ongrid-edge
# The ExecStartPre runs apply-pending-upgrade.sh which picks up any
# staged bundle and applies it before the new agent starts.

Der Rest dieser Seite erklärt, wie das alles tatsächlich funktioniert, sodass Sie es debuggen können, wenn es nicht klappt.

Manager-Upgrade: upgrade.sh

upgrade.sh lebt in jedem Release-Tarball und ist dafür gedacht, innerhalb des frisch extrahierten neueren Tarballs ausgeführt zu werden. Es nimmt an, dass es bereits eine Installation in ${ONGRID_INSTALL_DIR:-/opt/ongrid}/ gibt.

Der Reihe nach:

  1. Preflight. Verifiziert Docker + Compose v2, findet das bestehende .env. Bricht ab, wenn es keine gibt.
  2. Ermittelt alte vs. neue Version aus dem bestehenden .env und der VERSION-Datei des neuen Tarballs. Loggt beide — nützlich für Support-Tickets.
  3. docker compose down zum Freigeben der Datenvolumen für jeden Migrationsschritt.
  4. Re-asserts Datenverzeichnis-Eigentümerschaft unter ${ONGRID_DATA_DIR}/ (mysql, prom, loki, tempo, grafana, embeddings, qdrant). Image-uids haben sich lange nicht geändert, aber das ist der einzig sichere Default — Re-asserten ist idempotent.
  5. Re-staged Konfigurationen aus dem neuen Tarball nach /opt/ongrid/: docker-compose.yml, prometheus.yml, prometheus-rules.yml, loki-config.yaml, tempo-config.yaml, grafana/, searxng/, nginx.conf, frontier.yaml, die neuen edge/-Artefakte, die neue VERSION-Datei. .env bleibt erhaltenupgrade.sh überschreibt nie operator-editiertes env.
  6. Lädt neue Docker-Images (ongrid.tar, ongrid-web.tar, frontier.tar, falls vorhanden).
  7. Bumpt ONGRID_VERSION= in .env, sodass das nächste compose-up das neue Image-Tag aufnimmt.
  8. docker compose up -d mit dem neuen env.
  9. Pollt /healthz für 60s.
  10. Banner mit alt → neu Version, der Web-URL, nützlichen Next-Step-Befehlen.

Wenn vor Schritt 8 etwas fehlschlägt, kann der Operator nach Behebung des zugrundeliegenden Problems erneut ausführen — upgrade.sh ist idempotent. Wenn Schritt 9 fehlschlägt (/healthz gibt nie 200 zurück), sagen Ihnen die Manager-Logs von docker compose logs ongrid, was kaputt ist.

Für Zero-Downtime betreiben Sie ein Blue/Green-Setup mit zwei Manager-Hosts vor einem Loadbalancer; die OSS-Single-Host-Installation hat kurze Downtime während des Upgrades (~30-60s).

Wo die Upgrade-Artefakte herkommen: make package

Das ist der Operator-Pfad — wie Sie das Tarball bauen, wenn Sie aus dem Quellcode bauen statt ein Release zu ziehen. Aus einem Checkout von ongridio/ongrid:

bash
make package

Reihenfolge zählt; das ist, was make package tut:

  1. fetch-promtailpromtail-<os>-<arch>.zip aus dem Upstream Grafana-Release herunterladen, in bin/<os>-<arch>/promtail extrahieren. Gecacht.
  2. fetch-otelcol — dasselbe für otelcol-contrib.
  3. fetch-node-exporter — dasselbe für node_exporter.
  4. fetch-process-exporter — dasselbe für process_exporter.
  5. build-edge-allongrid-edge cross-kompilieren für linux/amd64, linux/arm64, darwin/amd64, darwin/arm64.
  6. docker-build — das ongrid:<version>-Image bauen.
  7. docker-build-brokersingchia/frontier:<ver> aus $FRONTIER_SRC bauen (oder überspringen, wenn bereits im lokalen Image-Store).
  8. docker-build-webongrid-web:<version> bauen (Frontend SPA + nginx).
  9. build-edge-bundleedge-bundle-linux-amd64-<ver>.tar.gz aus den losen Binaries zusammenstellen.
  10. dist/package.sh — alles in dist/stage/ongrid-<version>-linux-amd64/ lagern, die drei Images mit docker save sichern, das Ganze als tar.xz packen, das sha256-Sidecar berechnen, unter dist/out/ ablegen.

Die Ausgabe:

dist/out/ongrid-v0.7.160-linux-amd64.tar.xz
dist/out/ongrid-v0.7.160-linux-amd64.tar.xz.sha256

Das ist das Artefakt, das Sie auf den Prod-Host scpen und an ./upgrade.sh füttern.

Offline-RAG-Modell

Das BGE-Embedding-Modell ist keine package-Dependenz — es ist langsam, über CN-Netzwerke zu fetchen, sodass es ein einmaliger Schritt bleibt. Führen Sie make fetch-embedding-model einmal vor make package aus, wenn Sie möchten, dass ONGRID_EMBEDDING_PROVIDER=local bei einem Restore out of the Box funktioniert.

Edge-Upgrade: ADR-024 Stage-then-Swap

Der Benutzer-Pfad zum Upgraden einer Edge ist „Upgrade in der UI klicken" oder systemctl restart ongrid-edge, nachdem ein Bundle gelagert wurde. Was tatsächlich passiert, von oben nach unten:

1. Manager triggert, Edge fetcht

Bei „Upgrade all edges" (oder einer einzelnen Edge):

  • Der Manager liest dist/out/edge-bundle-<arch>-<ver>.tar.gz.sha256 aus /opt/ongrid/edge/ (dort von install.sh / upgrade.sh abgelegt).
  • Der Manager sendet MethodFetchPackage(url=https://<manager>/edge/<bundle>, sha256=<sha>, version=<ver>) über den Tunnel an die Ziel-Edges.
  • nginx bedient die Bundle-Bytes aus demselben /edge/-Verzeichnis.

2. Edge lagert

Die empfangende Edge:

  • Lädt das Bundle nach /tmp/ herunter.
  • Verifiziert die sha256 gegen das Manifest, das der Manager gesendet hat.
  • Untart nach /var/lib/ongrid-edge/.upgrade/incoming/.
  • Validiert jede <sha> <mode> <src> <dest>-Zeile der MANIFEST.txt (sha passt, src existiert).
  • Schreibt einen „ready"-Marker.
  • Exitt sauber. systemd startet die Unit gemäß Restart=always neu.

3. systemd's ExecStartPre läuft den Swap

Die Unit liefert mit:

ini
ExecStartPre=-+/usr/local/lib/ongrid-edge/apply-pending-upgrade.sh
ExecStart=/usr/local/bin/ongrid-edge

Das +-Präfix führt den Hook als root trotz User=ongrid-edge aus; das - lässt ein fehlendes/fehlschlagendes Skript mit Exit 0 ohne Blockieren der Unit exiten, sodass das Pre-Upgrade-Binary immer startet.

apply-pending-upgrade.sh tut der Reihe nach:

  1. Mode 1: Auto-Rollback, wenn ein vorheriges Upgrade gelaufen ist, aber nie healthy_marker passend zu last_upgrade_ver geschrieben hat. Stellt jede <dest>.previous über <dest> wieder her. Räumt das Staging-Verzeichnis.
  2. Mode 2: Bundle-Apply — für jede MANIFEST.txt-Zeile:
    • sha256 erneut verifizieren,
    • cp -p $dest $dest.previous (Snapshot für Rollback),
    • cp $src $dest.new auf demselben Dateisystem, sodass das finale Rename POSIX-atomar ist,
    • chmod $mode $dest.new,
    • mv -f $dest.new $dest.
  3. Mode 3: Legacy-Single-File-Apply für Rückwärtskompatibilität mit Edges, die noch nicht Bundle-Upgraded sind (nur das Agent-Binary, kein Manifest).
  4. Erfasst last_upgrade_at und last_upgrade_ver für den Next-Boot-Health-Check.

Dann führt ExecStart=/usr/local/bin/ongrid-edge das frisch gewechselte Binary aus.

4. Der neue Agent meldet gesund (oder nicht)

Der neue Agent, bei erfolgreichem Connect:

  • Schreibt /var/lib/ongrid-edge/.upgrade/healthy_marker mit der Version, die er läuft.
  • Meldet register über den Tunnel mit seiner neuen Version.

Wenn diese Datei existiert und mit last_upgrade_ver beim nächsten Boot passt, deklariert apply-pending-upgrade.sh Erfolg, prunet jede .previous, um Disk freizumachen, räumt das Staging-Verzeichnis.

Wenn nicht (Agent ist gecrasht, kann Manager nicht erreichen, irgendetwas anderes), triggert der nächste Boot Auto-Rollback: jede .previous wird wiederhergestellt, das Staging-Verzeichnis wird gewischt, die Edge läuft wieder die vorherige funktionierende Version. Der Operator sieht das in der UI (die Edge meldet weiterhin eine „alte" Version nach einem getriggerten Upgrade — ein Hinweis, dass etwas mit dem neuen Bundle nicht stimmt).

Bundle-Invarianten

Jede Datei, die die Edge wechselt, ist im Bundle; jede Datei im Bundle ist ein eigenständiges Binary oder Skript. Das ist nicht verhandelbar:

  • Das Agent-Binary (ongrid-edge)
  • Die Plugin-Binaries (promtail, otelcol-contrib, node_exporter, process_exporter)
  • Das Hook-Skript (apply-pending-upgrade.sh)

Plugin-Konfigurationen (promtail.yaml, otelcol.yaml) sind nicht im Bundle — sie leben in /etc/ongrid-edge/ und werden über den Tunnel als Live-Konfiguration zugestellt. So überschreibt ein Agent-Upgrade keine Konfiguration, die der Operator handeditiert hat.

Das Bundle nicht zurück in das Docker-Image backen

Wenn Sie aus dem Quellcode bauen, wird das Bundle von dist/build-edge-bundle.sh zur Package-Zeit auf dem Host gebaut, nicht im Container. ADR-032 erzwingt das — es zurück in das Image zu backen, doppelt-packt ~120 MB inkompressible Bytes und bricht die sha-Chain.

Wo Rollbacks leben

text
/usr/local/bin/ongrid-edge              # current
/usr/local/bin/ongrid-edge.previous     # last known good

/usr/local/lib/ongrid-edge/promtail
/usr/local/lib/ongrid-edge/promtail.previous

...etc.

/var/lib/ongrid-edge/.upgrade/
  last_upgrade_at                       # ISO timestamp
  last_upgrade_ver                      # version string
  healthy_marker                        # written by the new agent

Eine Boot-Sequenz nach einem getriggerten Upgrade sieht aus wie:

text
boot 1 (pre-upgrade):
  apply-pending-upgrade.sh sees nothing staged; exit 0
  ongrid-edge v0.7.159 runs

(manager pushes bundle, edge stages it, edge exits clean)

boot 2 (apply):
  apply-pending-upgrade.sh
    mode 1: no healthy_marker yet, but no last_upgrade_at either → skip
    mode 2: applies bundle. /usr/local/bin/ongrid-edge.previous = v0.7.159
                            /usr/local/bin/ongrid-edge        = v0.7.160
            writes last_upgrade_at, last_upgrade_ver=v0.7.160
            clears healthy_marker
  ongrid-edge v0.7.160 runs
  v0.7.160 connects, writes healthy_marker=v0.7.160

(reboot, e.g. host updates)

boot 3 (settle):
  apply-pending-upgrade.sh
    mode 1: last_upgrade_ver=v0.7.160, healthy_marker=v0.7.160 → success
            prunes all .previous files
            clears last_upgrade_at, last_upgrade_ver
  ongrid-edge v0.7.160 runs

Ein Failure-Szenario:

text
boot 2 (apply):
  apply-pending-upgrade.sh: applies bundle as above
  ongrid-edge v0.7.160 crashes immediately (e.g. config drift)
  systemd restarts repeatedly per Restart=always

boot 3 (rollback):
  apply-pending-upgrade.sh
    mode 1: last_upgrade_ver=v0.7.160, healthy_marker missing
            → roll back: restore .previous over each dest
              (ongrid-edge.previous → ongrid-edge, etc.)
            : > last_upgrade_at, rm -rf incoming/
  ongrid-edge v0.7.159 runs again (working)

Downgrading

Manager downgraden: das ältere Tarball extrahieren, ./upgrade.sh darin ausführen. Solange in den dazwischenliegenden Releases keine DB-Schema-Migration passiert ist, funktioniert das. Prüfen Sie die Release-Notes auf „breaking schema change"-Callouts, bevor Sie downgraden.

Edges downgraden: ein „Upgrade" aus der UI auf die ältere Bundle-Version triggern. Manager-Logik kümmert sich nicht darum, in welche Richtung die Version sich bewegt.

Was als Nächstes

  • Referenz / env — Umgebungsvariablen-Namen, deren Defaults sich zwischen Releases ändern.
  • Air-Gapped-Installation — wie Sie Artefakte auf einen privaten Webserver spiegeln, sodass apply-pending-upgrade.sh weiter Bundles ziehen kann, wenn der Manager selbst nicht im Internet ist.