---
title: "Mise à niveau sans interruption"
description: "Mettre à niveau une installation Quire autohébergée sans interruption."
image: "https://docs.quirelms.com/og.png"
---

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

# Mise à niveau sans interruption

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

Les règles se trouvent à la section 7 de `docs/architecture/23-ops.md` et à la section 4.1 de `docs/architecture/07-data.md`. Voici la procédure.

## La garantie qui rend la procédure sûre <!--quire:the-guarantee-that-makes-it-safe-->

**La version R fonctionne avec le schéma R et le schéma R moins un.** Chaque modification du schéma est divisée en trois étapes : expansion, transition et retrait.

1. **Expansion** : ajoutez la nouvelle colonne, table ou index. L’ancien code l’ignore.
2. **Transition**, pendant au moins une version : le nouveau code écrit les deux formes et lit la nouvelle; une tâche reprenable remplit les anciennes lignes.
3. **Retrait** : supprimez l’ancienne forme seule, dans une version ultérieure.

Ainsi, à chaque étape d’une mise à niveau progressive, les anciens et les nouveaux processus peuvent partager une base de données. Il n’y a pas de migration inverse : une migration ayant supprimé une colonne il y a une heure ne peut pas restaurer les lignes écrites pendant cette heure.

La tâche CI `schema-compat` vérifie cette garantie pour chaque version en exécutant les tests de la version précédente sur le nouveau schéma.

## Avant de commencer <!--quire:before-you-start-->

1. Lisez les notes de version. Une version qui nécessite une fenêtre de maintenance le précise et en donne la durée estimée; il n’y en a pas plus d’une par version.
2. Effectuez l’exercice de restauration ou confirmez qu’il a réussi pour cette version ([sauvegarde et restauration](/fr-CA/ops/backup-restore/)). Un exercice échoué bloque la mise à niveau.
3. Effectuez une sauvegarde de base : `docker compose -f docker/compose.yaml --profile backup run --rm backup`.

## Docker Compose, hôte unique <!--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
```

L’ordre est délibéré :

1. **Effectuez d’abord la migration**, pendant que l’ancienne version reçoit le trafic. Les migrations d’expansion lui sont invisibles.
2. **Mettez ensuite à niveau la couche Web.** À la réception de SIGTERM, chaque processus Web fait passer `/readyz` à l’état `draining`, termine les requêtes en cours dans les 30 secondes, ferme les flux avec une indication de reconnexion et s’arrête. `stop_grace_period` est de 40 secondes; Compose n’interrompt donc jamais une fermeture en bon état.
3. **Mettez les processus de travail à niveau en dernier**, afin que la forme d’événement la plus récente soit produite avant que le nouveau consommateur l’exige. Les processus cessent immédiatement de récupérer des tâches et disposent de 120 secondes; une tâche qui ne peut pas se terminer est récupérée ailleurs, ce qui est sûr parce que toutes les tâches sont idempotentes. Le planificateur cède son rôle de responsable à la prochaine exécution.

Sur un seul hôte, Compose remplace chaque conteneur tour à tour; il y a donc une brève interruption pour chaque service. Pour n’avoir aucune interruption, exécutez la couche Web dans deux conteneurs derrière votre propre mandataire (un fichier de remplacement qui ajoute un second service Web sans port publié) et recréez-les l’un après l’autre en attendant que chacun soit déclaré sain avant de passer au suivant.

## Plusieurs hôtes ou un orchestrateur <!--quire:several-hosts-or-an-orchestrator-->

Suivez le même ordre : migrez une seule fois à partir d’une tâche unique, déployez ensuite la couche Web avec une capacité supplémentaire de un et aucune instance indisponible, puis les processus de travail. Dirigez les sondes de préparation vers `/readyz` et celles de vitalité vers `/healthz`.

Avec des bases de données de locataires dédiées, l’étape `migrate` effectue les deux opérations : elle migre d’abord la base de contrôle, puis chaque base répertoriée dans `ops.tenant_database`, une à la fois et chacune sous son propre verrou. L’échec d’une base de locataire n’arrête pas les autres. Lorsque toutes sont traitées, l’étape compare les registres de migration et renvoie un code de sortie non nul à moins que chaque base ait appliqué exactement les migrations de la base de contrôle; elle indique alors chacune des bases en retard ou en avance. La même commande installe les tables de file d’attente dans chaque base, car le processus de travail consomme les tâches d’un locataire rattaché dans la base où elles ont été écrites.

```sh
bun apps/worker/src/migrate.ts   # what the Compose step runs
bun run db:migrate:all                            # the same, from a checkout
```
La migration normale et la configuration initiale installent aussi les documents juridiques anglais canoniques de l'exploitant Quire dans `ops.platform_policy_version`. L'installateur est idempotent : seuls les textes anglais manquants et exactement les textes temporaires créés par la migration sont remplacés. Les données de base sont archivées et une nouvelle version publiée est insérée; les références d'acceptation historiques et les textes sont conservés. Toute version authentique rédigée par l'exploitant, y compris une ébauche, est conservée et doit être gérée au moyen de la console des politiques de la plateforme. Les documents, les versions et le consentement relatifs aux politiques des locataires ne sont jamais modifiés par cette transition. Il s'agit de publier le texte de l'exploitant, et non d'une certification juridique ni de l'exécution automatique de ses promesses.


Chaque base dédiée est accessible sous le nom qui lui a été attribué. Une base enregistrée comme `env:QUIRE_DB_NORTHWIND_URL` nécessite :

| Variable | Utilisée pour |
| --- | --- |
| `QUIRE_DB_NORTHWIND_URL` | Le rôle d’application, pour la couche Web et le processus de travail |
| `QUIRE_DB_NORTHWIND_URL_MIGRATOR` | Le rôle de migration, pour cette commande et les déplacements |
| `QUIRE_DB_NORTHWIND_URL_SUPERUSER` | Facultative : réapplique l’amorçage (rôles, schémas, fonctions auxiliaires) avant la migration |

Une base enregistrée sans connexion `_MIGRATOR` est signalée comme un échec, jamais ignorée. La couche Web peut être déployée après la migration de la base de contrôle. Une base de locataire en retard d’une heure déclenche un avertissement; après un jour, elle déclenche une alerte.

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

Depuis la migration 0264, le corpus de référence utilise un index HNSW pgvector lorsque le serveur possède cette extension; le service `postgres` de Compose est compilé avec celle-ci (`docker/postgres.Dockerfile`). La première commande `migrate` après le changement d’image crée l’extension au moyen de l’amorçage superutilisateur, puis 0264 ajoute une colonne vectorielle générée et crée l’index. L’ajout de la colonne réécrit une fois `app.ai_chunk` sous un verrou exclusif; les requêtes de référence attendent pendant cette opération. Rien d’autre ne touche cette table.

Sur un serveur sans pgvector, 0264 inscrit un avis et ne change rien; la recherche reste exacte. Avec pgvector antérieur à la version 0.8, la colonne et l’index sont créés, mais la recherche reste exacte jusqu’à la mise à niveau de l’extension (`alter extension vector update`), car les balayages HNSW filtrés nécessitent les balayages itératifs de la version 0.8. Pour l’activer plus tard sur un serveur qui n’en dispose pas, installez l’extension, relancez l’amorçage (ou exécutez `create extension vector` comme superutilisateur), puis, sous le rôle `quire_migrator` :

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

L’opération est idempotente et renvoie `enabled` ou `unavailable`. Exécutez-la également sur chaque base de données de locataire dédiée.

## Retour en arrière <!--quire:rolling-back-->

Le retour en arrière du **code** est toujours possible : définissez `QUIRE_RELEASE` sur l’étiquette précédente, puis exécutez de nouveau `up -d`. Cela fonctionne parce que le schéma reste compatible dans les deux sens d’une version.

Le retour en arrière du **schéma** n’est pas offert. Voici ce qui ne peut pas être annulé et comment rétablir la situation :

| Non réversible | Rétablissement |
| --- | --- |
| Une migration de retrait ayant supprimé une colonne | Restaurez à un instant précis une nouvelle base antérieure à la suppression, extrayez les données et fusionnez-les |
| Une modification de données sur place | Même méthode, puis rapprochez les écritures ultérieures |
| Webhooks et événements envoyés | Événements compensatoires, jamais suppression |
| Courriel envoyé | Une personne rédige un suivi |
| Chaîne de hachage d’audit | Jamais réécrite; ajoutez une entrée de correction |

C’est pourquoi une migration de retrait est publiée seule : une restauration a alors un point de reprise propre.

## Vérifier la mise à niveau <!--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/fr-CA/ops/upgrade/index.mdx
