---
title: "Upgrade útfiere sûnder ûnderbrekking"
description: "Upgrade in selsbehearde Quire sûnder tsjinstûnderbrekking."
image: "https://docs.quirelms.com/og.png"
---

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

# Upgrade útfiere sûnder ûnderbrekking

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

De regels steane yn `docs/architecture/23-ops.md` seksje 7 en
`docs/architecture/07-data.md` seksje 4.1. Hjir stiet de proseduere.

## De garânsje dy't dit feilich makket <!--quire:the-guarantee-that-makes-it-safe-->

**Release R wurket korrekt mei skema R en skema R min ien.** Elke skemaferoaring wurdt
ferdield yn útwreidzje, oergong en ôfslute:

1. **Utwreidzje**: foegje de nije kolom, tabel of yndeks ta. Alde koade negearret dy.
2. **Oergong**, op syn minst ien release lang: nije koade skriuwt beide foarmen en lêst de
   nije; in hervatbere taak follet âlde rigen oan.
3. **Ofslute**: helje de âlde foarm fuort yn in lettere, aparte release.

Sa kinne âlde en nije prosessen by in stadige upgrade altyd ien database diele. Der binne
gjin migrations om werom te draaien: in migration dy't in oere lyn in kolom fuorthelle hat,
kin de rigen dy't yn dat oere skreaun binne net weromhelje.

De CI-taak `schema-compat` kontrolearret de garânsje by elke release troch de tests fan de
foarige release tsjin it nije skema út te fieren.

## Foardatst begjinst <!--quire:before-you-start-->

1. Lês de release-oantekeningen. In release dy't in ûnderhâldsfinster nedich hat, seit dat
   derby en jout in skatting; maksimaal ien per release.
2. Fier de restore drill út, of befêstigje dat er foar dizze release grien rûn is
   ([backup-restore.md](/fy/ops/backup-restore/)). In mislearre drill hâldt de upgrade tsjin.
3. Nim in base backup: `docker compose -f docker/compose.yaml --profile backup
   run --rm backup`.

## Docker Compose, ien 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
```

De folchoarder is mei opsetsin keazen:

1. **Earstoan migrearje**, wylst de âlde release ferkear betsjinnet. Utwreidmigrations
   binne dêr ûnsichtber foar.
2. **Dêrnei de web tier.** By SIGTERM set elk webproses `/readyz` op `draining`, makket
   aktive fersiken binnen 30 sekonden ôf, slút streams mei in hint om opnij te ferbinen en
   einiget. `stop_grace_period` is 40 sekonden, sadat Compose in sûne ôfsluting net ôfbrekt.
3. **As lêste de workers**, sadat de nijste foarm fan in barren produsearre wurdt foardat
   de nijste konsumint dy ferwachtet. Workers stopje daliks mei opheljen en krije 120 sekonden;
   in taak dy't net ôfmakke wurde kin, wurdt earne oars opnij oppakt. Dat is feilich om't elke
   taak idempotint is. De scheduler jout de liederskipsrol by de folgjende tik oer.

Op ien host ferfangt Compose elke container efterinoar, sadat der per tsjinst in koarte
ûnderbrekking is. Foar hielendal gjin ûnderbrekking, draai de web tier as twa containers efter
dyn eigen proxy (mei in override-bestân dat in twadde webtsjinst sûnder publisearre poarte
tafoeget) en meitsje se ien foar ien opnij oan. Wachtsje oant elk sûn is foardatst de folgjende
ferfangst.

## Meardere hosts of in orkestrator <!--quire:several-hosts-or-an-orchestrator-->

Brûk deselde folchoarder: migrearje ien kear út in inkele taak wei, rol dan de web tier út
mei ien ekstra en nul ûnbeskikber, en dêrnei de workers. Rjochtsje readiness-probes op
`/readyz` en liveness-probes op `/healthz`.

By tawijde tenant-databases docht `migrate` beide: earst de kontrôledatabase, dêrnei elke
database yn `ops.tenant_database`, ien foar ien en elk ûnder in eigen slot. In flater yn ien
tenant-database hâldt de oare net tsjin. As alle databases klear binne, ferliket it kommando
de migration-ledgers en einiget mei in net-nulstatus útsein as elke database krekt deselde
migrations tapast hat as de kontrôledatabase; it neamt elke database dy't efter of foar is.
It kommando set ek de wachtrigetabellen yn elke database op, om't de worker taken fan in
fêstsette tenant ophellet yn de database dêr't se skreaun binne.

```sh
bun apps/worker/src/migrate.ts   # what the Compose step runs
bun run db:migrate:all                            # the same, from a checkout
```

Elke tawijde database wurdt berikt fia de registrearre namme. In database registrearre as
`env:QUIRE_DB_NORTHWIND_URL` hat nedich:

| Fariabele | Brûkt foar |
| --- | --- |
| `QUIRE_DB_NORTHWIND_URL` | Applikaasjerol foar web tier en worker |
| `QUIRE_DB_NORTHWIND_URL_MIGRATOR` | Migratorrol foar dit kommando en ferhuzingen |
| `QUIRE_DB_NORTHWIND_URL_SUPERUSER` | Opsjoneel: docht de bootstrap (rollen, skema's, helpmiddels) opnij foar de migration |

In registrearre database sûnder `_MIGRATOR`-ferbining wurdt as flater rapportearre, nea
oerslein. De web tier kin rôlje as de kontrôledatabase klear is. In tenant-database dy't
in oere efter is jout in warskôging; nei in dei wurdt in alaarm stjoerd.

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

Fan migration 0264 ôf brûkt it grûningskorpus in pgvector HNSW-yndeks as de tsjinner de
útwreiding hat; de Compose-tsjinst `postgres` is dêrmei boud (`docker/postgres.Dockerfile`).
De earste `migrate` nei it wikseljen fan image makket de útwreiding oan fia de superuser-
bootstrap; dêrnei foeget 0264 in generearre vector-kolom ta en bout de yndeks. It tafoegjen
fan dy kolom skriuwt `app.ai_chunk` ien kear opnij ûnder in eksklusyf slot, sadat
grûningsoanfragen wachtsje; neat oars brûkt dy tabel.

Op in tsjinner sûnder pgvector jout 0264 in meidieling en feroaret neat; it opheljen bliuwt
eksakt. Mei pgvector âlder as 0.8 wurde kolom en yndeks wol boud, mar it opheljen bliuwt
eksakt oant de útwreiding bywurke is (`alter extension vector update`), om't filtere HNSW-
sykopdrachten de iterative scans fan 0.8 nedich hawwe. Om it letter yn te skeakeljen op in
tsjinner sûnder de útwreiding, ynstallearje dy, fier de bootstrap opnij út (of brûk
`create extension vector` as superuser), en fier dan as `quire_migrator` út:

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

It kommando is idempotint en jout `enabled` of `unavailable` werom. Fier it ek út op elke
tawijde tenant-database.

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

**Koade** weromdraaie kin altyd: set `QUIRE_RELEASE` op de foarige tag en fier `up -d`
opnij út. Dat wurket om't it skema yn beide rjochtingen kompatibel is binnen in release.

**Skema** weromdraaie wurdt net oanbean. Dit kin net ûngedien makke wurde; sa kinst herstelle:

| Net werom te draaien | Herstel |
| --- | --- |
| In contractmigration dy't in kolom wiske hat | Point-in-time-restore nei in nije database fan foar it fuortheljen; helje gegevens út en kombinearje se |
| In feroaring oan gegevens op it plak | Itselde, en harmonisearje dêrnei de skriuwaksjes sûnt dy tiid |
| Ferstjoerde webhooks en barrens | Kompensearjende barrens, nea wiskjen |
| Ferstjoerde e-mail | In persoan skriuwt it ferfolchberjocht |
| De audit-hashketen | Nea opnij skriuwe; foegje in korreksjeyngong ta |

Dêrom wurdt in contractmigration apart ferstjoerd: in restore hat dan in dúdlike grins.

## De upgrade kontrolearje <!--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/fy/ops/upgrade/index.mdx
