> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nora.my/llms.txt
> Use this file to discover all available pages before exploring further.

# 업데이트

> 온라인으로 업데이트를 확인하거나 오프라인 tarball 을 import 합니다. 앱 셸과 컨테이너 이미지는 각자 업데이트됩니다.

데스크톱 앱은 서로 독립적으로 업데이트되는 두 가지를 갖고 있습니다.

* **앱 셸** — 창을 렌더하고 스택을 관리하는 Tauri 바이너리입니다. 다운로드한 `Nora.app`, `Nora.exe`, `.AppImage` 가 이에 해당합니다.
* **컨테이너 이미지** — 실제로 Nora 를 돌리는 다섯 개 서비스 (`nora-server`, `nora-llm-bridge`, `postgres`, `redis`, `qdrant`) 입니다.

두 경로 모두 같은 팝업 창을 사용합니다. 팝업은 **Nora → \[Check for Updates…]** 또는 **Nora → \[Import Update…]** 메뉴로 엽니다.

## 온라인 — Check for updates

**Check for updates** 탭은 릴리스 매니페스트를 가져와 두 버전을 나란히 보여 줍니다.

* **Containers** 행은 `.env.onprem` 의 `NORA_IMAGE_TAG` 를 매니페스트의 최신 태그와 비교합니다. 새 태그가 있으면 **\[Update containers]** 를 누릅니다.
* **Desktop app** 행은 실행 중인 Tauri 바이너리를 매니페스트와 비교합니다. 새 빌드가 있으면 **\[Get app update →]** 를 누릅니다. Nora 가 다운로드 URL 을 기본 브라우저로 엽니다. 바이너리 교체는 최초 설치와 동일한 드래그 · `.msi` 흐름을 수동으로 진행합니다.

### 업데이트 마법사

**\[Update containers]** 를 누르면 팝업이 스텝 체크리스트로 바뀌고 로그가 아래에서 스트리밍됩니다. 네 개 스텝입니다.

| # | 스텝 | 하는 일 |
| - | - | - |
| 1 | Pin target version | `.env.onprem` 에 `NORA_IMAGE_TAG=<latest>` 를 써서 compose 보간이 참조하도록 합니다 |
| 2 | Pull updated images | `docker compose pull --ignore-buildable` 실행 |
| 3 | Restart stack | `docker compose up -d --force-recreate` 실행 |
| 4 | Wait for server to answer | 헬스 엔드포인트가 새 서버 응답을 낼 때까지 폴링 |

<Tip>
  업데이트는 Postgres · Redis · Qdrant 이미지에는 손대지 않습니다. Nora 릴리스는 이 세 이미지와 무관합니다.
</Tip>

### 매니페스트 위치

매니페스트는 기본으로 `https://updates.nora.my/latest.json` 에 있습니다. 스테이징 버킷이나 사내 아티팩트 서버로 릴리스를 미러링한다면 `NORA_UPDATE_MANIFEST_URL` 환경 변수로 오버라이드합니다.

### 매니페스트가 안 닿을 때

기업 프록시가 HTTPS 를 차단하거나 네트워크가 다운되었거나 URL 이 잘못 설정되어 있어도 팝업은 정상적으로 렌더됩니다. 온라인 섹션 옆에 힌트가 뜨고, **Import from file** 탭은 그대로 동작하므로 완전히 막히지 않습니다.

## 오프라인 — Import from file

**Import from file** 탭은 에어갭 운영자용입니다. `nora-onprem-<version>.tar.gz` 번들을 USB 나 사내 아티팩트 서버로 전달받은 뒤 팝업이 끝까지 처리합니다.

<Steps>
  <Step title="tarball 경로 지정">
    tarball 을 드롭 존에 끌어다 놓거나 전체 경로를 입력합니다.
  </Step>

  <Step title="[Import + restart] 클릭">
    팝업이 5 스텝 체크리스트로 전환되고 로그가 아래에서 스트리밍됩니다.
  </Step>
</Steps>

### Import 마법사

| # | 스텝 | 하는 일 |
| - | - | - |
| 1 | Extract tarball | `~/.nora/updates/` 아래 스크래치 디렉터리에 압축을 풉니다 |
| 2 | Load images into Docker | 번들된 `docker load -i docker-images.tar` 실행 |
| 3 | Update compose + pin version | `~/.nora/onprem/docker-compose.yml` 을 번들 사본으로 덮어쓰고, tarball 의 `VERSION` 파일 값을 `NORA_IMAGE_TAG` 로 씁니다 |
| 4 | Restart stack | `docker compose up -d --force-recreate` 실행 |
| 5 | Wait for server to answer | 헬스 엔드포인트가 새 서버 응답을 낼 때까지 폴링 |

스크래치 디렉터리는 restart 전에 지워집니다. 15 GB 짜리 tarball 이 compose 부팅 중에 메모리 매핑을 계속 잡고 있지 않도록 하기 위해서입니다.

## 버전 pin

성공한 업데이트는 새 태그를 `~/.nora/onprem/.env.onprem` 의 `NORA_IMAGE_TAG` 로 씁니다. 업데이트 팝업의 **Containers** 행은 언제나 마지막으로 실제 설치된 태그를 표시하므로, 팝업 표시와 실제 실행 사이의 drift 가 없습니다.

## 다운그레이드

일급 기능은 아니지만 동작은 합니다. 옛 셸 바이너리를 수동으로 설치하거나, 옛 버전의 tarball 을 import 합니다. compose 스택은 pinned 태그로 tear-down 되고 다시 up 됩니다.

<Warning>
  마이그레이션은 additive 입니다. 옛 서버가 새 DB 스키마 위에서는 데이터 손상 대신 부팅을 거절합니다. 스키마가 앞서갔다면 다운그레이드 전에 매칭되는 DB 스냅샷을 준비하세요.
</Warning>

## 다음

<CardGroup cols={2}>
  <Card title="Settings" icon="sliders" href="/ko/local-app/desktop/settings">
    라이선스 키, 호스트 포트, 리셋, 언인스톨.
  </Card>

  <Card title="에어갭 tarball" icon="box-archive" href="/ko/local-app/deploy/airgap">
    같은 tarball 을 처음부터 새 설치용으로 굽고 배포합니다.
  </Card>
</CardGroup>
