---
title: "Ngupgrade tanpa downtime"
description: "Ngupgrade Quire sing dihosting dhewe tanpa downtime."
image: "https://docs.quirelms.com/og.png"
---

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

# Ngupgrade tanpa downtime

<span id="upgrading-without-downtime"></span>

Aturane ana ing `docs/architecture/23-ops.md` bagean 7 lan `docs/architecture/07-data.md` bagean 4.1. Iki prosedure.

## Jaminan sing nggawe aman <!--quire:the-guarantee-that-makes-it-safe-->

**Rilis R mlaku kanthi bener nglawan skema R lan skema R minus siji.** Saben owahan skema dipisah dadi expand, transisi lan kontrak:

1. **Expand**: tambah kolom, tabel utawa indeks anyar. Kode lawas nglirwakake.
2. **Transisi**, kanggo paling ora siji rilis: kode anyar nulis kalorone wujud lan maca sing anyar; pagawean sing bisa diterusake ngisi baris lawas.
3. **Kontrak**: buwang wujud lawas, ing rilis mengko, dhewe.

Dadi ing saben wektu upgrade rolling, proses lawas lan anyar bisa nuduhake siji database. Ora ana migrasi mudhun: migrasi sing mbusak kolom sejam kepungkur ora bisa mbalekake baris sing ditulis ing jam kasebut.

Pagawean CI `schema-compat` mriksa jaminan ing saben rilis kanthi mbukak tes rilis sadurunge nglawan skema anyar.

## Sadurunge miwiti <!--quire:before-you-start-->

1. Waca cathetan rilis. Rilis sing butuh jendhela pangopènan ngandhani, kanthi estimasi; paling akeh siji per rilis.
2. Mbukak latihan restore, utawa konfirmasi mlaku ijo kanggo rilis iki ([backup-restore.md](/jv/ops/backup-restore/)). Latihan gagal mblokir upgrade.
3. Jupuk serep dasar: `docker compose -f docker/compose.yaml --profile backup run --rm backup`.

## Docker Compose, siji host <!--quire:docker-compose-one-host-->

```sh
export QUIRE_RELEASE=2026.10.0            # or set it in docker/.env
docker compose -f docker/compose.yaml pull   # or build
docker compose -f docker/compose.yaml run --rm migrate
docker compose -f docker/compose.yaml up -d --no-deps web content collab
docker compose -f docker/compose.yaml up -d --no-deps worker scheduler
```

Urutane disengaja:

1. **Migrasi dhisik**, selagi rilis lawas ngladeni traffic. Migrasi expand ora katon kanggo iku.
2. **Tier web sabanjure.** Ing SIGTERM saben proses web ngganti `/readyz` dadi `draining`, ngrampungake panjalukan sing mlaku sajrone 30 detik, nutup stream kanthi hint sambung maneh, lan metu. `stop_grace_period` iku 40 detik supaya Compose ora tau motong drain sing sehat.
3. **Worker pungkasan**, supaya wujud prastawa paling anyar diprodhuksi sadurunge konsumen paling anyar ngarepake. Worker mandheg njupuk langsung lan entuk 120 detik; pagawean sing ora bisa rampung dijupuk maneh ing papan liya, sing aman amarga saben pagawean idempoten. Scheduler masrahake kepemimpinan ing tick sabanjure.

Ing siji host, Compose ngganti saben container giliran, supaya ana jeda cendhak per layanan. Kanggo tanpa jeda babar pisan, mbukak tier web minangka rong container ing mburine proxy dhewe (file override nambah layanan web kapindho tanpa port sing diterbitake), lan gawe maneh siji-siji, ngenteni saben nglaporake sehat sadurunge sabanjure.

## Pirang host utawa orchestrator <!--quire:several-hosts-or-an-orchestrator-->

Gunakake urutan sing padha: migrasi sapisan saka siji pagawean, banjur gulung tier web kanthi surge siji lan unavailable nol, banjur worker. Tudingake probe readiness menyang `/readyz` lan liveness menyang `/healthz`.

Kanthi database tenant khusus, langkah `migrate` nindakake kalorone: migrasi database kontrol dhisik, banjur saben database sing kadhaptar ing `ops.tenant_database`, siji-siji, saben ing sangisore kunce dhewe. Gagal ing siji database tenant ora mungkasi liyane. Nalika saben database rampung mbandhingake ledger migrasi lan metu non-nol kajaba saben database wis ngetrapake persis migrasi sing ditrapake database kontrol, nyebutake saben sing ketinggalan utawa kedhisikan. Prentah sing padha nginstal tabel antrean ing saben database, amarga worker ngonsumsi pagawean tenant sing disematake ing panggonan ditulis.

```sh
bun apps/worker/src/migrate.ts   # what the Compose step runs
bun run db:migrate:all                            # the same, from a checkout
```
Migrasi normal lan persiyapan wiwitan uga nginstal dokumen hukum Inggris kanonis operator Quire menyang `ops.platform_policy_version`. Pemasang kasebut idempoten: mung badan Inggris sing ilang lan persis badan placeholder sing digawe migrasi sing diganti. Seed diarsipake lan versi terbitan anyar dilebokake; referensi panampa historis lan badan dilestarekake. Saben versi asli sing ditulis operator, kalebu draf, dilestarekake lan kudu dikelola liwat konsol Kebijakan platform. Dokumen, versi, lan idin kabijakan tenant ora tau diowahi dening cutover iki. Iki minangka publikasi teks operator, dudu sertifikasi hukum utawa kawujudan otomatis saka janji-janjine.


Saben database khusus digayuh liwat jeneng sing didaftarake. Database sing kadhaptar minangka `env:QUIRE_DB_NORTHWIND_URL` butuh:

| Variabel | Digunakake kanggo |
| --- | --- |
| `QUIRE_DB_NORTHWIND_URL` | Peran aplikasi, kanggo tier web lan worker |
| `QUIRE_DB_NORTHWIND_URL_MIGRATOR` | Peran migrator, kanggo prentah iki lan kanggo pindah |
| `QUIRE_DB_NORTHWIND_URL_SUPERUSER` | Opsional: ngetrapake maneh bootstrap (peran, skema, helper) sadurunge migrasi |

Database kadhaptar tanpa sambungan `_MIGRATOR` dilaporake minangka gagal, ora tau dilewati. Tier web bisa gulung yen database kontrol rampung. Database tenant sing ketinggalan sejam ngelingake; sedina manggil.

## pgvector <!--quire:pgvector-->

Wiwit migrasi 0264 korpus grounding nggunakake indeks HNSW pgvector ing panggonan server duwe ekstensi; layanan `postgres` Compose dibangun karo iku (`docker/postgres.Dockerfile`). `migrate` kapisan sawise ganti image nggawe ekstensi liwat bootstrap superuser, lan 0264 banjur nambah kolom vektor sing digawe lan mbangun indeks. Nambah kolom nulis maneh `app.ai_chunk` sapisan ing sangisore kunci eksklusif, dadi panjalukan grounding ngenteni; ora ana liyane sing ndemek tabel kasebut.

Ing server tanpa pgvector, 0264 nyathet kabar lan ora ngowahi apa-apa, lan retrieval tetep persis. Kanthi pgvector luwih lawas saka 0.8 kolom lan indeks dibangun nanging retrieval tetep persis nganti ekstensi diupgrade (`alter extension vector update`), amarga scan HNSW sing disaring butuh scan iteratif 0.8. Kanggo nguripake mengko ing server tanpane, instal ekstensi, mbukak bootstrap maneh (utawa `create extension vector` minangka superuser), banjur minangka `quire_migrator`:

```sql
set maintenance_work_mem = '1GB';  -- the HNSW build is much faster in memory
select ops.ai_chunk_enable_vector_index();
```

Iki idempoten lan mbalekake `enabled` utawa `unavailable`. Mbukak ing saben database tenant khusus uga.

## Mbalekake <!--quire:rolling-back-->

Mbalekake **kode** tansah kasedhiya: setel `QUIRE_RELEASE` menyang tag sadurunge lan `up -d` maneh. Iku bisa amarga skema kompatibel ing kalorone arah sajrone rilis.

Mbalekake **skema** ora ditawakake. Apa sing ora bisa dibatalake, lan carane pulih:

| Ora bisa dibalekake | Pamulihan |
| --- | --- |
| Migrasi kontrak sing mbusak kolom | Restore point-in-time menyang sadurunge mbusak menyang database anyar, ekstrak, gabung |
| Owahan data ing panggonan | Sing padha, banjur rekonsiliasi tulisan wiwit |
| Webhook lan prastawa sing dikirim | Prastawa kompensasi, ora tau pambusakan |
| Email sing dikirim | Manungsa nulis tindak lanjut |
| Rante hash audit | Ora tau ditulis maneh; tambah entri koreksi |

Mula migrasi kontrak dikirim dhewe: restore banjur duwe wates resik.

## Mriksa upgrade <!--quire:checking-the-upgrade-->

```sh
docker compose -f docker/compose.yaml ps           # every service healthy
curl -fsS http://localhost:8080/readyz             # ready, and what is configured
docker compose -f docker/compose.yaml logs migrate # the migrations applied
```

Source: https://docs.quirelms.com/jv/ops/upgrade/index.mdx
