---
title: "Opgraderinger uden nedetid"
description: "Opgrader en selvhostet Quire-instans uden nedetid."
image: "https://docs.quirelms.com/og.png"
---

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

# Opgraderinger uden nedetid

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

Reglerne står i afsnit 7 i `docs/architecture/23-ops.md` og afsnit 4.1 i
`docs/architecture/07-data.md`. Dette er fremgangsmåden.

## Garantien, der gør det sikkert <!--quire:the-guarantee-that-makes-it-safe-->

**Udgivelse R fungerer korrekt med skema R og R minus én.** Hver
skemaændring opdeles i udvidelse, overgang og kontraktion:

1. **Udvidelse**: Tilføj den nye kolonne, tabel eller det nye indeks. Gammel kode ignorerer det.
2. **Overgang**, i mindst én udgivelse: Ny kode skriver begge former og
   læser den nye; et job, der kan genoptages, udfylder gamle rækker i baggrunden.
3. **Kontraktion**: Fjern den gamle form alene i en senere udgivelse.

Derfor kan gammel og ny proces til enhver tid under en løbende opgradering dele én
database. Der findes ingen nedgraderingsmigreringer: En migrering, der slettede en kolonne for en time siden,
kan ikke genskabe de rækker, der er skrevet i den time.

CI-jobbet `schema-compat` kontrollerer garantien ved hver udgivelse ved at køre
den forrige udgivelses tests mod det nye skema.

## Før du begynder <!--quire:before-you-start-->

1. Læs udgivelsesnoterne. En udgivelse, der kræver et vedligeholdelsesvindue, angiver det
   sammen med et estimat; højst én pr. udgivelse.
2. Kør gendannelsesøvelsen, eller bekræft, at den gennemførtes uden fejl for denne udgivelse
   ([backup-restore.md](/da/ops/backup-restore/)). En mislykket øvelse blokerer
   opgraderingen.
3. Tag en grundbackup: `docker compose -f docker/compose.yaml --profile backup
   run --rm backup`.

## Docker Compose på én vært <!--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
```

Rækkefølgen er bevidst:

1. **Kør migreringer først**, mens den gamle udgivelse betjener trafikken. Udvidelsesmigreringer
   er usynlige for den.
2. **Dernæst weblaget.** Ved SIGTERM sætter hver webproces `/readyz` til
   `draining`, afslutter igangværende forespørgsler inden for 30 sekunder, lukker streams
   med et hint om genforbindelse og afslutter. `stop_grace_period` er 40 sekunder, så
   Compose aldrig afbryder en sund nedlukning.
3. **Workers til sidst**, så den nyeste hændelsesform produceres, før den nyeste
   forbruger forventer den. Workers stopper straks med at hente job og får 120 sekunder;
   et job, der ikke kan afsluttes, hentes igen et andet sted, hvilket er sikkert, fordi hvert
   job er idempotent. Scheduler overdrager lederskabet ved næste tidsinterval.

På én vært udskifter Compose hver container efter tur, så der opstår en kort pause
for hver tjeneste. Hvis du slet ikke vil have en pause, kan du køre weblaget som to containere
bag din egen proxy (med en override-fil, der tilføjer en webtjeneste nummer to uden offentliggjort port)
og genskabe dem én ad gangen. Vent, indtil hver enkelt melder sig sund, før den næste udskiftes.

## Flere værter eller en orkestrator <!--quire:several-hosts-or-an-orchestrator-->

Brug samme rækkefølge: Kør migrering én gang i et enkelt job, udrul derefter weblaget
med én ekstra instans og nul utilgængelige instanser, og udrul til sidst workers. Ret
readiness-prober mod `/readyz` og liveness-prober mod `/healthz`.

Med dedikerede lejerdatabaser migrerer trinnet `migrate` begge dele: Først kontroldatabasen,
og derefter hver database, der er angivet i
`ops.tenant_database`, én ad gangen og under sin egen lås. En fejl i én lejerdatabase stopper ikke de
øvrige. Når alle databaser er færdige, sammenlignes migreringsloggene, og kommandoen afslutter med en fejlstatus,
medmindre alle databaser har anvendt præcis de migreringer, kontroldatabasen har. Den angiver hver
database, der er bagud eller foran. Den samme kommando installerer køtabeller i hver
database, fordi worker behandler job for fastlåste lejere dér, hvor de blev skrevet.

```sh
bun apps/worker/src/migrate.ts   # what the Compose step runs
bun run db:migrate:all                            # the same, from a checkout
```
Almindelig migrering og førstegangsopsætning installerer også de kanoniske engelske juridiske dokumenter fra Quire-operatøren i `ops.platform_policy_version`. Installationsprogrammet er idempotent: kun manglende engelske tekster og præcis de pladsholdertekster, som migreringen har seedet, erstattes. Seeds arkiveres, og en ny udgivet version indsættes; historiske acceptreferencer og tekster bevares. Enhver ægte operatørskrevet version, også en kladde, bevares og skal forvaltes via platformens Politik-konsol. Lejerens politiske dokumenter, versioner og samtykke ændres aldrig ved denne overgang. Dette er udgivelse af operatørens tekst, ikke juridisk certificering eller automatisk opfyldelse af dens løfter.


Hver dedikeret database tilgås gennem det navn, den er registreret under.
En database registreret som `env:QUIRE_DB_NORTHWIND_URL` kræver:

| Variabel | Anvendes til |
| --- | --- |
| `QUIRE_DB_NORTHWIND_URL` | Applikationsrollen for weblaget og worker |
| `QUIRE_DB_NORTHWIND_URL_MIGRATOR` | Migratorrollen til denne kommando og flytninger |
| `QUIRE_DB_NORTHWIND_URL_SUPERUSER` | Valgfri: genanvender bootstrap (roller, skemaer og hjælpefunktioner) før migrering |

En registreret database uden `_MIGRATOR`-forbindelse rapporteres som en fejl,
aldrig sprunget over. Weblaget kan udrulles, når kontroldatabasen er klar. En lejerdatabase, der er en time bagud, udløser en advarsel; efter én dag sendes en alarm.

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

Fra migrering 0264 bruger grounding-korpuset et pgvector-HNSW-indeks, når serveren har
udvidelsen. Compose-tjenesten `postgres` bygges med den
(`docker/postgres.Dockerfile`). Den første `migrate` efter skift til nye
images opretter udvidelsen via superuser-bootstrap, og migrering 0264 tilføjer derefter en
genereret vektorkolonne og opbygger indekset. Tilføjelsen omskriver `app.ai_chunk` én gang under en eksklusiv lås, så forespørgsler om grounding venter på den; intet andet berører tabellen.

På en server uden pgvector logger 0264 en bemærkning og ændrer intet; søgning forbliver præcis. Med en pgvector-version før 0.8 opbygges kolonnen og indekset, men søgning forbliver præcis, indtil udvidelsen opgraderes
(`alter extension vector update`), fordi filtrerede HNSW-søgninger kræver de iterative scanninger fra 0.8. Hvis du vil aktivere dette senere på en server, der mangler pgvector, skal du installere udvidelsen, køre bootstrap igen (eller `create extension vector` som superuser) og derefter køre følgende som `quire_migrator`:

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

Kommandoen er idempotent og returnerer `enabled` eller `unavailable`. Kør den også på hver
dedikerede lejerdatabase.

## Tilbageførsel <!--quire:rolling-back-->

Tilbageførsel af **kode** er altid mulig: Angiv det forrige tag i `QUIRE_RELEASE`, og kør `up -d` igen. Det fungerer, fordi skemaet er kompatibelt i begge retninger inden for en udgivelse.

Tilbageførsel af **skema** tilbydes ikke. Dette kan ikke fortrydes, og sådan gendannes det:

| Kan ikke fortrydes | Gendannelse |
| --- | --- |
| En kontraktionsmigrering, der slettede en kolonne | Gendan til et tidspunkt før sletningen i en ny database, udtræk data, og flet dem |
| En ændring af data på stedet | Det samme, og afstem derefter skrivninger siden da |
| Sendte webhooks og hændelser | Kompenserende hændelser, aldrig sletning |
| Sendt e-mail | Et menneske skriver opfølgningen |
| Audit-hashkæden | Omskrives aldrig; tilføj en korrigerende post |

Derfor udsendes en kontraktionsmigrering alene: Gendannelsen har dermed en klar grænse.

## Kontrollér opgraderingen <!--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/da/ops/upgrade/index.mdx
