Skip to content

Upgrade

Dos binarios para upgradear: el manager (stack docker-compose) y los edges (uno por host). Ambos siguen el mismo flujo conceptual: stagear los nuevos artefactos, swappearlos atómicamente, caer en la versión previa automáticamente si la nueva no levanta sana.

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 (todos, en paralelo, desde la UI):

  • Edges → Upgrade all — el manager empuja MethodFetchPackage a cada edge conectado, cada uno descarga el bundle staged desde https://<manager>/edge/, lo stagea, reinicia, swap, corre. Las fallas auto-rollback en el siguiente boot.

O para un único edge desde la 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.

El resto de esta página explica cómo funciona todo eso realmente, para que puedas debugarlo cuando no funcione.

Upgrade del manager: upgrade.sh

upgrade.sh vive en cada tarball de release y está pensado para correrse dentro del tarball más nuevo recién extraído. Asume que ya hay una instalación en ${ONGRID_INSTALL_DIR:-/opt/ongrid}/.

En orden:

  1. Preflight. Verifica docker + compose v2, encuentra el .env existente. Aborta si no hay.
  2. Determina versión vieja vs nueva del .env existente y el archivo VERSION del nuevo tarball. Loguea ambos — útil para tickets de soporte.
  3. docker compose down para liberar los volúmenes de datos para cualquier paso de migración.
  4. Re-afirma ownership de data dir bajo ${ONGRID_DATA_DIR}/ (mysql, prom, loki, tempo, grafana, embeddings, qdrant). Los uids de imagen no han cambiado hace tiempo pero este es el único default seguro — re-afirmar es idempotente.
  5. Re-stagea configs del nuevo tarball a /opt/ongrid/: docker-compose.yml, prometheus.yml, prometheus-rules.yml, loki-config.yaml, tempo-config.yaml, grafana/, searxng/, nginx.conf, frontier.yaml, los nuevos artefactos edge/, el nuevo archivo VERSION. .env se preservaupgrade.sh nunca sobrescribe env editado por el operador.
  6. Carga nuevas imágenes docker (ongrid.tar, ongrid-web.tar, frontier.tar si está presente).
  7. Sube ONGRID_VERSION= en .env para que el siguiente compose-up recoja el nuevo image tag.
  8. docker compose up -d con el nuevo env.
  9. Sondea /healthz por 60s.
  10. Banner con versión vieja → nueva, la URL Web, comandos útiles para próximos pasos.

Si algo falla antes del paso 8, el operador puede re-ejecutar después de arreglar el problema subyacente — upgrade.sh es idempotente. Si el paso 9 falla (/healthz nunca devuelve 200), los logs del manager de docker compose logs ongrid te dirán qué está roto.

Para zero-downtime, corre un setup blue/green con dos hosts manager delante de un load balancer; la instalación single-host OSS tiene brief downtime durante upgrade (~30-60s).

De dónde vienen los artefactos de upgrade: make package

Esta es la ruta del operador — cómo construir el tarball si estás construyendo desde el código fuente en vez de jalar una release. Desde un checkout de ongridio/ongrid:

bash
make package

El orden importa; esto es lo que hace make package:

  1. fetch-promtail — descarga promtail-<os>-<arch>.zip de la release upstream de Grafana, extrae a bin/<os>-<arch>/promtail. Cached.
  2. fetch-otelcol — lo mismo para otelcol-contrib.
  3. fetch-node-exporter — lo mismo para node_exporter.
  4. fetch-process-exporter — lo mismo para process_exporter.
  5. build-edge-all — cross-compilar ongrid-edge para linux/amd64, linux/arm64, darwin/amd64, darwin/arm64.
  6. docker-build — construir la imagen ongrid:<version>.
  7. docker-build-broker — construir singchia/frontier:<ver> desde $FRONTIER_SRC (o saltarse si ya está en el image store local).
  8. docker-build-web — construir ongrid-web:<version> (SPA del frontend + nginx).
  9. build-edge-bundle — ensamblar edge-bundle-linux-amd64-<ver>.tar.gz desde los binarios sueltos.
  10. dist/package.sh — stagea todo a dist/stage/ongrid-<version>-linux-amd64/, hace docker save de las tres imágenes, tar.xz de todo, computa el sidecar sha256, lo deja bajo dist/out/.

La salida:

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

Ese es el artefacto que haces scp al host de prod y le pasas a ./upgrade.sh.

Modelo RAG offline

El modelo de embedding BGE no es una dep de package — es lento de fetchear sobre redes CN, así que se queda como un paso one-off. Corre make fetch-embedding-model una vez antes de make package si quieres que ONGRID_EMBEDDING_PROVIDER=local funcione de fábrica en un restore.

Upgrade del edge: stage-then-swap de ADR-024

La ruta del usuario para upgradear un edge es "haz clic en Upgrade en la UI" o systemctl restart ongrid-edge después de que un bundle se ha staged. Lo que realmente pasa, de arriba abajo:

1. El manager dispara, el edge fetchea

En "Upgrade all edges" (o un solo edge):

  • El manager lee dist/out/edge-bundle-<arch>-<ver>.tar.gz.sha256 desde /opt/ongrid/edge/ (puesto ahí por install.sh / upgrade.sh).
  • El manager envía MethodFetchPackage(url=https://<manager>/edge/<bundle>, sha256=<sha>, version=<ver>) sobre el túnel a los edges target.
  • nginx sirve los bytes del bundle desde el mismo dir /edge/.

2. El edge stagea

El edge receptor:

  • Descarga el bundle a /tmp/.
  • Verifica el sha256 contra el manifest que envió el manager.
  • Hace untar a /var/lib/ongrid-edge/.upgrade/incoming/.
  • Valida cada línea <sha> <mode> <src> <dest> de MANIFEST.txt (sha matchea, src existe).
  • Escribe un marker "ready".
  • Sale limpio. systemd reinicia la unit por Restart=always.

3. El ExecStartPre de systemd corre el swap

La unit viene con:

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

El prefijo + ejecuta el hook como root a pesar de User=ongrid-edge; el - deja que un script faltante/fallido salga 0 sin bloquear la unit, para que el binario pre-upgrade siempre arranque.

apply-pending-upgrade.sh hace, en orden:

  1. Modo 1: auto-rollback si un upgrade previo corrió pero nunca escribió healthy_marker matcheando last_upgrade_ver. Restaura cada <dest>.previous sobre <dest>. Limpia el dir de staging.
  2. Modo 2: bundle apply — para cada línea de MANIFEST.txt:
    • re-verifica el sha256,
    • cp -p $dest $dest.previous (snapshot para rollback),
    • cp $src $dest.new en el mismo filesystem para que el rename final sea POSIX-atómico,
    • chmod $mode $dest.new,
    • mv -f $dest.new $dest.
  3. Modo 3: apply legacy de archivo único para back-compat con edges que aún no han sido bundle-upgraded (solo el binario del agente, sin manifest).
  4. Graba last_upgrade_at y last_upgrade_ver para el health check del siguiente boot.

Luego ExecStart=/usr/local/bin/ongrid-edge corre el binario recién-swapped.

4. El nuevo agente reporta sano (o no)

El nuevo agente, ante connect exitoso:

  • Escribe /var/lib/ongrid-edge/.upgrade/healthy_marker con la versión que está corriendo.
  • Reporta register sobre el túnel con su nueva versión.

Si ese archivo existe y matchea last_upgrade_ver para el siguiente boot, apply-pending-upgrade.sh declara éxito, elimina cada .previous para liberar disco, limpia el dir de staging.

Si no (el agente crasheó, no puede alcanzar al manager, cualquier otra cosa), el siguiente boot dispara auto-rollback: cada .previous se restaura, el dir de staging se barre, el edge corre la versión previa que funcionaba de nuevo. El operador ve esto en la UI (el edge sigue reportando una versión "vieja" después de un upgrade disparado — un indicio de que algo está mal con el nuevo bundle).

Invariantes del bundle

Cada archivo que el edge swappea está en el bundle; cada archivo en el bundle es un binario o script autocontenido. Esto es no negociable:

  • El binario del agente (ongrid-edge)
  • Los binarios de plugin (promtail, otelcol-contrib, node_exporter, process_exporter)
  • El script hook (apply-pending-upgrade.sh)

Los configs de plugin (promtail.yaml, otelcol.yaml) no están en el bundle — viven en /etc/ongrid-edge/ y se entregan sobre el túnel como config en vivo. Así un upgrade del agente no clobberea un config que el operador editó a mano.

No hornees el bundle de vuelta en la imagen docker

Si estás construyendo desde fuente, el bundle lo construye dist/build-edge-bundle.sh en el host al momento de package, no en el contenedor. ADR-032 refuerza esto — re-hornearlo en la imagen double-packea ~120 MB de bytes no comprimibles y rompe la cadena sha.

Dónde viven los rollbacks

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

Una secuencia de boot después de un upgrade disparado se ve como:

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

Un escenario de falla:

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

Downgrading del manager: extrae el tarball más viejo, corre ./upgrade.sh dentro de él. Mientras no haya pasado migración de schema de DB en las releases intermedias, esto funciona. Revisa los release notes por "cambio de schema breaking" antes de hacer downgrade.

Downgrading de edges: dispara un "upgrade" desde la UI a la versión más vieja del bundle. La lógica del manager no le importa en qué dirección se mueve la versión.

Qué sigue

  • Reference / env — nombres de env var cuyos defaults cambian entre releases.
  • Instalación air-gapped — cómo espejar artefactos a un webserver privado para que apply-pending-upgrade.sh pueda seguir jalando bundles cuando el propio manager no está en internet.