Апгрейд
Два бинаря для апгрейда: manager (docker-compose стек) и edge'и (один на хост). Оба следуют одному концептуальному flow: stage новые артефакты, swap их атомарно, fall back на предыдущую версию автоматически, если новая не приходит в здоровое состояние.
TL;DR
Manager:
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.shEdge'и (все, параллельно, из UI):
- Edges → Upgrade all — manager пушит
MethodFetchPackageкаждому подключённому edge, каждый скачивает stage'нутый bundle изhttps://<manager>/edge/, stage'ит, рестартит, swap'ит, запускает. Сбои авто-rollback'аются на следующей загрузке.
Или для одиночного edge из shell:
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.Остальная часть страницы объясняет, как всё это на самом деле работает, чтобы вы могли отлаживать, когда не работает.
Апгрейд manager: upgrade.sh
upgrade.sh живёт в каждом release-tarball и предназначен для запуска внутри свежераспакованного нового tarball. Он предполагает, что уже есть установка в ${ONGRID_INSTALL_DIR:-/opt/ongrid}/.
По порядку:
- Preflight. Верифицирует docker + compose v2, находит существующий
.env. Срывается, если такого нет. - Определяет старую vs новую версию из существующего
.envиVERSIONфайла нового tarball. Логирует обе — полезно для support- тикетов. docker compose down, чтобы освободить data-volumes для любого migration-шага.- Переутверждает ownership data-директорий под
${ONGRID_DATA_DIR}/(mysql, prom, loki, tempo, grafana, embeddings, qdrant). Image- uid'ы давно не менялись, но это единственный безопасный дефолт — переутверждение идемпотентно. - Restage конфиги из нового tarball в
/opt/ongrid/:docker-compose.yml,prometheus.yml,prometheus-rules.yml,loki-config.yaml,tempo-config.yaml,grafana/,searxng/,nginx.conf,frontier.yaml, новыеedge/артефакты, новыйVERSIONфайл..envсохраняется —upgrade.shникогда не перезаписывает operator-edited env. - Загружает новые docker-образы (
ongrid.tar,ongrid-web.tar,frontier.tar, если присутствуют). - Bumps
ONGRID_VERSION=в.env, так что следующий compose-up берёт новый image-tag. docker compose up -dс новым env.- Polls
/healthz60с. - Banner со старой → новой версией, Web URL, полезными командами следующего шага.
Если что-то падает до шага 8, оператор может перезапустить после фикса underlying-issue — upgrade.sh идемпотентен. Если шаг 9 падает (/healthz никогда не возвращает 200), manager-логи из docker compose logs ongrid расскажут вам, что сломано.
Для zero-downtime запустите blue/green setup с двумя manager-хостами за load balancer; OSS single-host установка — это короткий downtime во время апгрейда (~30-60с).
Откуда приходят upgrade-артефакты: make package
Это operator-путь — как вы собираете tarball, если вы собираете из исходников вместо pull релиза. Из checkout ongridio/ongrid:
make packageПорядок важен; вот что делает make package:
fetch-promtail— скачатьpromtail-<os>-<arch>.zipс upstream Grafana-релиза, распаковать вbin/<os>-<arch>/promtail. Кэшируется.fetch-otelcol— то же дляotelcol-contrib.fetch-node-exporter— то же дляnode_exporter.fetch-process-exporter— то же дляprocess_exporter.build-edge-all— кросс-компиляцияongrid-edgeдляlinux/amd64,linux/arm64,darwin/amd64,darwin/arm64.docker-build— собрать образongrid:<version>.docker-build-broker— собратьsingchia/frontier:<ver>из$FRONTIER_SRC(или пропустить, если уже в local image store).docker-build-web— собратьongrid-web:<version>(frontend SPA + nginx).build-edge-bundle— собратьedge-bundle-linux-amd64-<ver>.tar.gzиз loose-бинарей.dist/package.sh— stage'ит всё вdist/stage/ongrid-<version>-linux-amd64/,docker save-ит три образа,tar.xz-ит всё это, вычисляет sha256 sidecar, кладёт подdist/out/.
Output:
dist/out/ongrid-v0.7.160-linux-amd64.tar.xz
dist/out/ongrid-v0.7.160-linux-amd64.tar.xz.sha256Это артефакт, который вы scp-ите на prod-хост и подаёте ./upgrade.sh.
Offline RAG модель
BGE embedding-модель не package-зависимость — она медленно fetch'ится по CN-сетям, так что остаётся one-off шагом. Запустите make fetch-embedding-model один раз до make package, если хотите, чтобы ONGRID_EMBEDDING_PROVIDER=local работал из коробки при восстановлении.
Апгрейд edge: ADR-024 stage-then-swap
User-путь для апгрейда edge — это «кликнуть Upgrade в UI» или systemctl restart ongrid-edge после того, как bundle был stage'нут. Что на самом деле происходит, сверху вниз:
1. Manager триггерит, edge fetch'ит
При «Upgrade all edges» (или одного edge):
- Manager читает
dist/out/edge-bundle-<arch>-<ver>.tar.gz.sha256из/opt/ongrid/edge/(положено тудаinstall.sh/upgrade.sh). - Manager отправляет
MethodFetchPackage(url=https://<manager>/edge/<bundle>, sha256=<sha>, version=<ver>)через туннель целевым edge'ам. - nginx сервит bundle-байты из той же
/edge/директории.
2. Edge stage'ит
Получающий edge:
- Скачивает bundle в
/tmp/. - Верифицирует sha256 против манифеста, который послал manager.
- Untar'ит в
/var/lib/ongrid-edge/.upgrade/incoming/. - Валидирует каждую
<sha> <mode> <src> <dest>строкуMANIFEST.txt(sha совпадает, src существует). - Пишет «ready» marker.
- Чисто выходит. systemd рестартит unit по
Restart=always.
3. ExecStartPre systemd запускает swap
Unit отгружается с:
ExecStartPre=-+/usr/local/lib/ongrid-edge/apply-pending-upgrade.sh
ExecStart=/usr/local/bin/ongrid-edgeПрефикс + запускает hook как root несмотря на User=ongrid-edge; - позволяет отсутствующему/падающему скрипту выйти 0 без блокировки unit, так что pre-upgrade бинарь всегда стартует.
apply-pending-upgrade.sh делает, по порядку:
- Mode 1: auto-rollback, если предыдущий апгрейд запустился, но никогда не записал
healthy_marker, совпадающий сlast_upgrade_ver. Восстанавливает каждый<dest>.previousповерх<dest>. Чистит staging-директорию. - Mode 2: bundle apply — для каждой строки
MANIFEST.txt:- пере-верифицировать sha256,
cp -p $dest $dest.previous(snapshot для rollback),cp $src $dest.newна той же файловой системе, так что финальный rename — POSIX-атомарный,chmod $mode $dest.new,mv -f $dest.new $dest.
- Mode 3: legacy single-file apply для back-compat с edge'ями, которые ещё не были bundle-upgraded (только agent-бинарь, без манифеста).
- Записывает
last_upgrade_atиlast_upgrade_verдля next-boot health check.
Затем ExecStart=/usr/local/bin/ongrid-edge запускает свежеsрапнутый бинарь.
4. Новый агент репортит healthy (или нет)
Новый агент, при успешном connect:
- Пишет
/var/lib/ongrid-edge/.upgrade/healthy_markerс версией, которую он запускает. - Репортит
registerчерез туннель со своей новой версией.
Если файл существует и совпадает с last_upgrade_ver к следующей загрузке, apply-pending-upgrade.sh объявляет успех, пrune'ит каждый .previous, чтобы освободить диск, чистит staging-директорию.
Если нет (агент упал, не может дотянуться до manager, что-то ещё), следующая загрузка триггерит auto-rollback: каждый .previous восстанавливается, staging-директория стирается, edge запускает предыдущую рабочую версию снова. Оператор видит это в UI (edge продолжает репортить «старую» версию после триггернутого апгрейда — clue, что что-то не так с новым bundle).
Bundle-инварианты
Каждый файл, который edge swap'ит, в bundle; каждый файл в bundle — это самодостаточный бинарь или скрипт. Это non-negotiable:
- Agent-бинарь (
ongrid-edge) - Plugin-бинари (
promtail,otelcol-contrib,node_exporter,process_exporter) - Hook-скрипт (
apply-pending-upgrade.sh)
Plugin-конфиги (promtail.yaml, otelcol.yaml) не в bundle — они живут в /etc/ongrid-edge/ и доставляются через туннель как live config. Так апгрейд агента не затирает конфиг, который оператор отредактировал вручную.
Не запекайте bundle обратно в docker-образ
Если вы собираете из исходников, bundle собирается dist/build-edge-bundle.sh на хосте во время package-сборки, не в контейнере. ADR-032 форсит это — пере-запекание его в образ двойной-pack'ит ~120 MB несжимаемых байт и ломает sha- цепь.
Где живут rollback'и
/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 agentBoot-последовательность после триггернутого апгрейда выглядит как:
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 runsFailure-сценарий:
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)Downgrade
Downgrade manager: распакуйте старый tarball, запустите ./upgrade.sh внутри. Пока миграции схемы БД не было в промежуточных релизах, это работает. Проверьте release-notes на любые «breaking schema change» предупреждения до downgrade.
Downgrade edge'ей: триггерните «upgrade» из UI до более старой версии bundle. Manager-логике неважно, в каком направлении версия движется.
Что дальше
- Reference / env — имена env-переменных, чьи defaults меняются между релизами.
- Air-gapped установка — как зеркалировать артефакты на приватный webserver, чтобы
apply-pending-upgrade.shмог всё ещё pull bundle, когда сам manager не в интернете.