업그레이드
업그레이드할 바이너리는 두 개입니다. 매니저 (docker-compose 스택) 와 edge (호스트당 하나). 둘 다 같은 개념적 흐름을 따릅니다: 새 아티팩트를 스테이지하고, 원자적으로 swap 하고, 새 것이 정상 기동되지 못하면 자동으로 이전 버전으로 폴백.
TL;DR
매니저:
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.shEdges (전부, 병렬, UI 에서):
- Edges → Upgrade all — 매니저가 연결된 모든 edge 에
MethodFetchPackage를 push, 각 edge 가https://<manager>/edge/에서 스테이징된 번들을 다운로드, 스테이지, 재시작, swap, 실행. 실패는 다음 부팅 시 자동 롤백.
또는 셸에서 단일 edge:
sudo systemctl restart ongrid-edge
# ExecStartPre 가 apply-pending-upgrade.sh 를 실행하여 스테이징된 번들이 있으면
# 새 에이전트가 시작하기 전에 적용.이 페이지의 나머지는 위 동작이 실제로 어떻게 동작하는지 설명합니다 — 동작하지 않을 때 디버그할 수 있도록.
매니저 업그레이드: upgrade.sh
upgrade.sh 는 모든 릴리스 tarball 에 있으며 새로 추출된 새 tarball 내부에서 실행해야 합니다. ${ONGRID_INSTALL_DIR:-/opt/ongrid}/ 에 기존 설치가 있다고 가정합니다.
순서대로:
- Preflight. docker + compose v2 검증, 기존
.env탐색. 없으면 종료. - 기존
.env와 새 tarball 의VERSION파일에서 이전 vs 새 버전 판단. 둘 다 로깅 — 지원 티켓에 유용. - 마이그레이션 단계를 위해 데이터 볼륨을 해제하기 위한
docker compose down. ${ONGRID_DATA_DIR}/아래 데이터 디렉터리 소유권 재단언 (mysql, prom, loki, tempo, grafana, embeddings, qdrant). 이미지 uid 는 오래 변하지 않았지만 이것이 유일한 안전 기본 — 재단언은 멱등.- 새 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는 운영자 편집 env 를 절대 덮어쓰지 않음. - 새 docker 이미지 로드 (
ongrid.tar,ongrid-web.tar,frontier.tar가 있다면). - 다음 compose-up 이 새 이미지 태그를 픽업하도록
.env의ONGRID_VERSION=범프. - 새 env 와 함께
docker compose up -d. /healthz폴링 60 초.- 이전 → 새 버전, Web URL, 유용한 다음 단계 명령으로 배너 출력.
8 단계 전에 실패하면 운영자가 근본 이슈를 고친 후 재실행 가능 — upgrade.sh 는 멱등. 9 단계가 실패하면 (/healthz 가 200 을 돌려주지 않으면), docker compose logs ongrid 가 무엇이 망가졌는지 알려 줍니다.
무중단을 위해서는 로드 밸런서 앞에 두 매니저 호스트로 blue/green 셋업; OSS 단일 호스트 설치는 업그레이드 중 짧은 중단 (~30-60 초) 입니다.
업그레이드 아티팩트의 출처: make package
이것은 운영자 경로 — 릴리스를 풀하는 대신 소스에서 빌드하는 경우 tarball 을 빌드하는 방법. ongridio/ongrid 체크아웃에서:
make package순서가 중요합니다. make package 가 하는 것:
fetch-promtail— 업스트림 Grafana 릴리스에서promtail-<os>-<arch>.zip다운로드,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—$FRONTIER_SRC로부터singchia/frontier:<ver>빌드 (이미 로컬 이미지 스토어에 있으면 건너뜀).docker-build-web—ongrid-web:<version>(프론트엔드 SPA + nginx) 빌드.build-edge-bundle— loose 바이너리에서edge-bundle-linux-amd64-<ver>.tar.gz조립.dist/package.sh— 모든 것을dist/stage/ongrid-<version>-linux-amd64/로 스테이지, 세 이미지를docker save, 전체를tar.xz압축, sha256 사이드카 계산,dist/out/아래 배포.
출력:
dist/out/ongrid-v0.7.160-linux-amd64.tar.xz
dist/out/ongrid-v0.7.160-linux-amd64.tar.xz.sha256이것이 prod 호스트로 scp 해서 ./upgrade.sh 에 주는 아티팩트입니다.
오프라인 RAG 모델
BGE 임베딩 모델은 package 의존성이 아닙니다 — CN 네트워크에서 fetch 가 느려서 일회성 단계로 둡니다. 복원 시 ONGRID_EMBEDDING_PROVIDER=local 이 박스 그대로 동작하길 원한다면 make package 전에 make fetch-embedding-model 을 한 번 실행하세요.
Edge 업그레이드: ADR-024 stage-then-swap
edge 업그레이드의 사용자 경로 는 "UI 에서 Upgrade 클릭" 또는 번들이 스테이징된 후 systemctl restart ongrid-edge 입니다. 실제로 일어나는 일, 위에서 아래로:
1. 매니저 트리거, edge fetch
"Upgrade all edges" (또는 단일 edge) 시:
- 매니저가
/opt/ongrid/edge/(install.sh / upgrade.sh 가 놓아 둠) 의dist/out/edge-bundle-<arch>-<ver>.tar.gz.sha256를 읽음. - 매니저가 대상 edge 에 터널 위
MethodFetchPackage(url=https://<manager>/edge/<bundle>, sha256=<sha>, version=<ver>)전송. - nginx 가 같은
/edge/디렉터리에서 번들 바이트를 제공.
2. Edge 스테이지
수신 edge:
- 번들을
/tmp/로 다운로드. - 매니저가 보낸 manifest 대비 sha256 검증.
/var/lib/ongrid-edge/.upgrade/incoming/으로 untar.MANIFEST.txt의 각<sha> <mode> <src> <dest>라인 검증 (sha 일치, src 존재).- "ready" 마커 작성.
- 깨끗하게 종료. systemd 가
Restart=always에 따라 unit 재시작.
3. systemd 의 ExecStartPre 가 swap 실행
unit 은 다음과 함께 옵니다:
ExecStartPre=-+/usr/local/lib/ongrid-edge/apply-pending-upgrade.sh
ExecStart=/usr/local/bin/ongrid-edge+ 접두사는 User=ongrid-edge 임에도 훅을 root 로 실행시킵니다; - 는 빠짐/실패 스크립트가 unit 을 블록하지 않고 exit 0 으로 끝낼 수 있게 해, 업그레이드 전 바이너리가 항상 시작되게 합니다.
apply-pending-upgrade.sh 가 순서대로 수행:
- Mode 1: auto-rollback — 이전 업그레이드가 실행되었으나
last_upgrade_ver와 매칭되는healthy_marker가 쓰여지지 않았다면. 모든<dest>.previous를<dest>위로 복원. 스테이징 디렉터리 지움. - Mode 2: bundle apply — 각
MANIFEST.txt라인에 대해:- sha256 재검증,
cp -p $dest $dest.previous(롤백용 스냅샷),- 최종 rename 이 POSIX 원자적이도록 같은 파일시스템에서
cp $src $dest.new, chmod $mode $dest.new,mv -f $dest.new $dest.
- Mode 3: legacy single-file apply — 아직 번들 업그레이드되지 않은 edge 용 (매니페스트 없는, 에이전트 바이너리만) 의 하위 호환.
- 다음 부팅 헬스 체크용으로
last_upgrade_at과last_upgrade_ver기록.
그런 다음 ExecStart=/usr/local/bin/ongrid-edge 가 새로 swap 된 바이너리를 실행.
4. 새 에이전트가 정상 보고 (또는 아님)
새 에이전트가 성공적으로 연결되면:
/var/lib/ongrid-edge/.upgrade/healthy_marker를 실행 중인 버전과 함께 작성.- 새 버전으로 터널을 통해
register보고.
다음 부팅 때까지 그 파일이 존재하고 last_upgrade_ver 와 일치하면, apply-pending-upgrade.sh 가 성공 선언, 디스크 확보를 위해 모든 .previous 정리, 스테이징 디렉터리 지움.
그렇지 않으면 (에이전트 크래시, 매니저 도달 불가 등) 다음 부팅이 auto-rollback 트리거: 모든 .previous 복원, 스테이징 디렉터리 지움, edge 가 이전 동작 버전을 다시 실행. 운영자는 UI 에서 이를 봅니다 (트리거된 업그레이드 후 edge 가 계속 "이전" 버전을 보고 — 새 번들에 문제가 있다는 단서).
번들 불변량
edge 가 swap 하는 모든 파일은 번들에 있고, 번들의 모든 파일은 자체 완결형 바이너리 또는 스크립트입니다. 이것은 협상 불가:
- 에이전트 바이너리 (
ongrid-edge) - 플러그인 바이너리 (
promtail,otelcol-contrib,node_exporter,process_exporter) - 훅 스크립트 (
apply-pending-upgrade.sh)
플러그인 설정 (promtail.yaml, otelcol.yaml) 은 번들에 없습니다 — /etc/ongrid-edge/ 에 있고, 터널을 통해 라이브 설정으로 전달됩니다. 그러면 에이전트 업그레이드가 운영자가 손수 편집한 설정을 짓밟지 않습니다.
번들을 docker 이미지에 다시 굽지 말 것
소스에서 빌드한다면 번들은 패키지 시점 호스트 에서 dist/build-edge-bundle.sh 가 빌드합니다. 컨테이너 안이 아닙니다. ADR-032 가 이를 강제합니다 — 이미지에 다시 구우면 비압축 ~120 MB 가 이중 패킹되어 sha 체인이 깨집니다.
롤백 파일 위치
/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트리거된 업그레이드 후 부팅 시퀀스:
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실패 시나리오:
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)다운그레이드
매니저 다운그레이드: 이전 tarball 추출, 그 안에서 ./upgrade.sh 실행. 중간 릴리스에서 DB 스키마 마이그레이션이 없다면 동작합니다. 다운그레이드 전에 릴리스 노트에서 "breaking schema change" 콜아웃을 확인하세요.
Edge 다운그레이드: UI 에서 이전 번들 버전으로 "업그레이드" 트리거. 매니저 로직은 버전이 어느 방향으로 움직이는지 신경 쓰지 않습니다.
다음은
- Reference / env — 릴리스 간에 기본값이 바뀌는 환경 변수 이름.
- 에어갭 설치 — 매니저가 인터넷에 있지 않을 때
apply-pending-upgrade.sh가 번들을 풀할 수 있도록 아티팩트를 사설 웹서버에 미러링하는 방법.