Actualizaciones
Una versión nueva del motor puede traer solo código, migraciones de sus tablas propias o un pin nuevo de whatsmeow con migraciones de su store. La regla que cuida todo el procedimiento: nunca queda un número abierto en dos procesos a la vez. El traspaso de cada sesión se confirma en la base.
Hay dos caminos:
- Con canario: la versión nueva atiende unas pocas instancias mientras la actual sigue con las demás. Solo si todas las migraciones nuevas son compatibles.
- Con corte: se para el motor, se migra y se arranca la versión nueva. Para migraciones incompatibles o un store de whatsmeow nuevo.
Las migraciones
Sección titulada «Las migraciones»El motor tiene dos juegos de tablas, y cada uno se migra distinto:
| Tablas | Herramienta | Quién la corre | Vuelta atrás |
|---|---|---|---|
| Las propias (comandos, ledger, outbox, Ajustes…) | goose, embebidas en el binario | motor al arrancar (bajo lock), o migrate up / migrate todo |
Depende de su marca de compatibilidad |
El store de whatsmeow (whatsmeow_*: las sesiones de los números) |
El upgrade del SDK, bajo advisory lock | Solo migrate whatsmeow o migrate todo |
Nunca hay down: se restaura un backup |
Desde la 00033, cada migración propia declara si un binario anterior puede convivir con ella:
-- motor:rollback compatible (agrega columnas que aceptan NULL, que la versión anterior no lee)-- +goose Up…Un test hace que ninguna quede sin marca. Al aplicarla, el motor guarda la marca en la base. Así, un binario más viejo que la base sabe si puede arrancar:
- si todo lo que no conoce es compatible, arranca sin migrar y lo avisa en el log;
- si hay una incompatible (o sin marca), se niega a arrancar con un mensaje que nombra la migración y su motivo («rollback bloqueado»). Nunca en silencio.
migrate down existe solo para desarrollo (APP_ENV=desarrollo). En producción, volver de una
migración incompatible es restaurar el backup previo.
0. Antes de empezar
Sección titulada «0. Antes de empezar»- Un backup de menos de 24 h y verificado (Despliegue y backup). Sin eso, no se actualiza.
- Las notas de la versión: qué migraciones trae y su marca de rollback.
1. La verificación previa
Sección titulada «1. La verificación previa»Con el binario nuevo contra la base de hoy. Es de solo lectura:
# Con la imagen nueva en el servicio migrate del compose:docker compose run --rm --no-deps migrate verificarDice la versión de las tablas propias (en la base y en el binario), cada migración pendiente con su marca y su motivo, el store de whatsmeow (base y binario), el último backup y si el motor está en modo restaurado. Termina con «Sin bloqueos.» o con la lista de BLOQUEA y un código de salida distinto de cero. Bloquean:
- una base más nueva que el binario con una migración que este no entiende (incompatible o sin marca);
- un store de whatsmeow más nuevo que el binario.
Una migración pendiente incompatible no bloquea: la lista con «va con corte (sin canario)».
2. Con canario
Sección titulada «2. Con canario»El canario prueba la versión nueva con unas pocas instancias. Solo vale si todas las migraciones pendientes son compatibles y si el principal que corre ya entiende el traspaso.
-
Marca las instancias del canario: ficha de la instancia → Transporte → Canario (superadmin). Empieza con una o dos de bajo riesgo.
-
Arranca la versión nueva como canario, contra la misma base, como un segundo servicio:
Ventana de terminal motor --canarioComprueba que el principal entiende el traspaso, migra las tablas propias (solo si todas las pendientes son compatibles; con una incompatible se niega a arrancar y dice cuál) y toma el dominio canario. El principal suelta las instancias marcadas y el canario las abre. Cada uno concilia cada 30 s, así que el traspaso tarda hasta un minuto. Operación muestra el proceso canario vivo y cuántas instancias tiene.
-
Observa un rato: Operación, Inicio, las alertas, los eventos de esas instancias y las entregas. El canario no corre el backup diario.
-
Si algo va mal, para el proceso canario. El principal ve que dejó de latir y vuelve a abrir sus instancias (hasta 15 s más el margen del dueño). Las migraciones compatibles que aplicó no le molestan.
-
Si va bien, promueve: para el principal, arranca la versión nueva como principal (sin
--canario) y después para el canario. Las instancias marcadas vuelven al principal nuevo. Desmarca el canario cuando quieras.
Si la versión trae un store nuevo de whatsmeow, el canario no lo sube. Corre migrate whatsmeow
con la versión nueva antes de promover, sabiendo que no tiene vuelta atrás.
3. Con corte
Sección titulada «3. Con corte»Para migraciones incompatibles, un store de whatsmeow nuevo o un principal sin el protocolo de traspaso.
- Backup verificado (paso 0) y
migrate verificar. - Para el motor con
SIGTERM(docker compose stop motor). El apagado ordenado deja de tomar trabajo, termina lo que está en vuelo (lo que ya salió a WhatsApp queda como enviado aunque el proceso se esté cerrando), cierra el outbox y suelta las sesiones. Lo que no alcanzó a salir queda en la cola para el próximo proceso. - Migra con el binario nuevo:
migrate todo(las tablas propias y el store de whatsmeow). En el compose de Despliegue y backup es el serviciomigratecon la imagen nueva. - Arranca la versión nueva y revisa Operación (migraciones al día, el proceso dueño) e Inicio.
# Con la imagen nueva en los servicios migrate y motor:docker compose stop motordocker compose up -d migrate # migrate todo, y terminadocker compose up -d motordocker compose exec motor /app/motorctl diagnostico4. Rollback
Sección titulada «4. Rollback»| Lo que se aplicó | Cómo se vuelve |
|---|---|
| Solo código, o migraciones compatibles | Arranca el binario anterior: ve la base más nueva, comprueba que lo que no conoce es compatible y arranca sin migrar (lo avisa en el log). |
| Una migración incompatible | El binario anterior se niega a arrancar («rollback bloqueado», con la migración y su motivo). Se vuelve restaurando el backup previo. |
| Un store de whatsmeow nuevo | Igual: el binario anterior se niega a arrancar y se restaura el backup previo. Nunca hay down sobre las tablas de whatsmeow. |
El restore es aislado y empieza en modo restaurado: sigue Restore aislado.
Síntomas
Sección titulada «Síntomas»| Lo que ves | Qué es | Qué hacer |
|---|---|---|
| El motor no arranca y el log dice «rollback bloqueado» | Un binario anterior ante una migración incompatible o un store nuevo | No lo fuerces: despliega la versión nueva o restaura el backup previo. |
| «el canario no aplica migraciones incompatibles» | La versión trae una migración incompatible | Actualiza con corte. |
«el principal que está corriendo es de una versión que no entiende el traspaso al canario» o «canario bloqueado» con motor_canario_bloqueado 1 |
El principal es anterior al protocolo de traspaso | Para el canario y actualiza con corte. El canario no abrió ni tocó las instancias del principal. |
/health/ready en 503: «La base tiene migraciones más nuevas que este binario, y no son compatibles con él» |
Un binario viejo contra una base nueva | Restaura el backup previo o despliega la versión nueva. |
/health/ready en 503: «El store de whatsmeow no está al día: corre migrate whatsmeow.» |
El store no se migró | Corre migrate whatsmeow (o migrate todo). |
| Una instancia que no abre en ningún proceso durante el canario | El canario murió sin soltarla | Mira Operación → Instancias (proceso, canario, dueño). El principal la recupera cuando vence el latido del canario. |
La alerta cliente_desactualizado |
WhatsApp rechaza la versión del cliente (ClientOutdated) |
La instancia queda detenida, sin bucle de reconexión. Se arregla con una versión del motor con el pin nuevo de whatsmeow y reconectando la instancia. |
El procedimiento del repositorio es docs/runbooks/actualizacion.md.