---
title: "Actualizar sin tiempo de inactividad"
description: "Actualiza Quire autoalojado sin tiempo de inactividad."
image: "https://docs.quirelms.com/og.png"
---

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

# Actualizar sin tiempo de inactividad

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

Las reglas aparecen en la sección 7 de `docs/architecture/23-ops.md` y en la sección 4.1 de `docs/architecture/07-data.md`. Este es el procedimiento.

## La garantía que lo hace seguro <!--quire:the-guarantee-that-makes-it-safe-->

**La versión R se ejecuta correctamente con el esquema R y con el esquema R menos uno.** Cada cambio de esquema se divide en ampliación, transición y contracción:

1. **Ampliación**: añade la nueva columna, tabla o índice. El código antiguo lo ignora.
2. **Transición**, durante al menos una versión: el código nuevo escribe en ambos formatos y lee el nuevo; un trabajo reanudable completa los registros antiguos.
3. **Contracción**: elimina el formato antiguo en una versión posterior, en un despliegue independiente.

Así, en todo momento de una actualización gradual, los procesos antiguos y nuevos pueden compartir una base de datos. No hay migraciones inversas: una migración que eliminó una columna hace una hora no puede recuperar las filas escritas durante esa hora.

El trabajo de CI `schema-compat` comprueba la garantía en cada versión ejecutando las pruebas de la versión anterior con el esquema nuevo.

## Antes de empezar <!--quire:before-you-start-->

1. Lee las notas de la versión. Si una versión requiere una ventana de mantenimiento, se indicará junto con la duración estimada; como máximo habrá una por versión.
2. Ejecuta el simulacro de restauración o confirma que se completó correctamente con esta versión ([backup-restore.md](/es/ops/backup-restore/)). Si el simulacro falla, no se puede continuar con la actualización.
3. Crea una copia base: `docker compose -f docker/compose.yaml --profile backup run --rm backup`.

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

El orden es deliberado:

1. **Primero, migrar**, mientras la versión anterior sigue atendiendo solicitudes. Las migraciones de ampliación son invisibles para ella.
2. **Después, la capa web.** Al recibir SIGTERM, cada proceso web cambia `/readyz` a `draining`, termina las solicitudes en curso en un máximo de 30 segundos, cierra los flujos con una indicación para volver a conectarse y sale. `stop_grace_period` es de 40 segundos, así Compose nunca interrumpe un apagado correcto.
3. **Por último, los workers**, para que la versión más reciente del consumidor no se adelante al formato de evento que se produce. Los workers dejan de obtener trabajos de inmediato y disponen de 120 segundos; si un trabajo no termina, otro worker lo vuelve a obtener. Es seguro porque todos los trabajos son idempotentes. El scheduler cede el liderazgo en su siguiente turno.

En un solo host, Compose reemplaza cada contenedor por turnos, así que hay una breve interrupción por servicio. Para eliminar por completo las interrupciones, ejecuta la capa web como dos contenedores detrás de tu propio proxy (con un archivo de configuración alternativa que añada un segundo servicio web sin puerto publicado) y vuelve a crearlos de uno en uno, esperando a que cada uno indique que está saludable antes de continuar.

## Varios hosts o un orquestador <!--quire:several-hosts-or-an-orchestrator-->

Sigue el mismo orden: ejecuta una sola tarea de migración y luego actualiza gradualmente la capa web, con un recurso adicional disponible y ninguno no disponible, y después los workers. Configura las comprobaciones de preparación en `/readyz` y las de disponibilidad en `/healthz`.

Con bases de datos de tenants dedicadas, el paso `migrate` realiza ambas tareas: primero migra la base de datos de control y después cada base de datos indicada en `ops.tenant_database`, de una en una y con su propio bloqueo. Un fallo en una base de datos de tenant no detiene las demás. Cuando termina con todas, compara los registros de migración y devuelve un código distinto de cero, salvo que todas hayan aplicado exactamente las mismas migraciones que la base de datos de control; además, indica cuáles van retrasadas o adelantadas. El mismo comando instala las tablas de la cola en cada base de datos, porque el worker consume en ella los trabajos de los tenants fijados a esa base.

```sh
bun apps/worker/src/migrate.ts   # what the Compose step runs
bun run db:migrate:all                            # the same, from a checkout
```
La migración normal y la configuración inicial también instalan los documentos legales canónicos en inglés del operador de Quire en `ops.platform_policy_version`. El instalador es idempotente: solo se sustituyen los textos en inglés que falten y exactamente los textos provisionales creados por la migración. Las semillas se archivan y se inserta una nueva versión publicada; las referencias históricas de aceptación y los textos se conservan. Cualquier versión auténtica redactada por el operador, incluido un borrador, se conserva y debe gestionarse desde la consola de Políticas de la plataforma. Los documentos, versiones y consentimiento de las políticas de inquilinos nunca cambian con esta transición. Esto es publicación de texto del operador, no certificación legal ni cumplimiento automático de sus promesas.


Se accede a cada base de datos dedicada por el nombre con el que está registrada. Una base de datos registrada como `env:QUIRE_DB_NORTHWIND_URL` necesita:

| Variable | Se usa para |
| --- | --- |
| `QUIRE_DB_NORTHWIND_URL` | Rol de la aplicación, para la capa web y el worker |
| `QUIRE_DB_NORTHWIND_URL_MIGRATOR` | Rol de migración, para este comando y para las transferencias |
| `QUIRE_DB_NORTHWIND_URL_SUPERUSER` | Opcional: vuelve a aplicar la inicialización (roles, esquemas y funciones auxiliares) antes de migrar |

Si una base de datos registrada no tiene conexión `_MIGRATOR`, se informa como fallo y nunca se omite. La capa web puede actualizarse cuando termina la base de datos de control. Si la base de datos de un tenant lleva una hora de retraso, se genera una advertencia; tras un día, una alerta de prioridad alta.

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

A partir de la migración 0264, el corpus de fundamentación usa un índice pgvector HNSW si el servidor tiene la extensión; el servicio `postgres` de Compose se compila con ella (`docker/postgres.Dockerfile`). En el primer `migrate` después de cambiar las imágenes, la inicialización de superusuario crea la extensión y, a continuación, la migración 0264 añade una columna vectorial generada y crea el índice. La columna reescribe una vez `app.ai_chunk` con un bloqueo exclusivo, por lo que las solicitudes de fundamentación esperan; nada más toca esa tabla.

En un servidor sin pgvector, la migración 0264 muestra un aviso y no cambia nada, y la recuperación sigue siendo exacta. Si pgvector es anterior a la versión 0.8, se crean la columna y el índice, pero la recuperación sigue siendo exacta hasta que se actualiza la extensión (`alter extension vector update`), porque los recorridos HNSW filtrados requieren los recorridos iterativos de la versión 0.8. Para activarla más adelante en un servidor que no la tenga, instala la extensión, vuelve a ejecutar la inicialización (o `create extension vector` como superusuario) y luego, como `quire_migrator`, ejecuta:

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

Es idempotente y devuelve `enabled` o `unavailable`. Ejecútala también en cada base de datos de tenant dedicada.

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

Siempre se puede revertir el **código**: establece `QUIRE_RELEASE` en la etiqueta anterior y vuelve a ejecutar `up -d`. Funciona porque, dentro de una versión, el esquema es compatible en ambos sentidos.

No se admite revertir el **esquema**. Esto es lo que no se puede deshacer y cómo recuperarse:

| No reversible | Recuperación |
| --- | --- |
| Una migración de contracción que eliminó una columna | Restauración a un momento anterior a la eliminación en una base nueva; después, extraer y combinar los datos |
| Un cambio de datos en el sitio | Lo mismo y, después, conciliar las escrituras posteriores |
| Webhooks y eventos enviados | Eventos compensatorios, nunca eliminaciones |
| Correo enviado | Una persona redacta el mensaje de seguimiento |
| Cadena hash de auditoría | No se reescribe nunca; se añade una entrada de corrección |

Por eso una migración de contracción se despliega sola: así, la restauración tiene un límite claro.

## Comprobar la actualización <!--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/es/ops/upgrade/index.mdx
