Instalar el motor
El motor es un solo servicio (API, coordinador de sesiones y workers en un proceso) que se distribuye como una imagen de contenedor. Vive en tu red privada: tus apps le hablan por HTTP y él habla con WhatsApp. Esta página levanta un motor para empezar a probar; para producción, backups y actualizaciones, sigue con Despliegue y backup.
Requisitos
Sección titulada «Requisitos»| Pieza | Para qué | Notas |
|---|---|---|
| Docker con Compose | Correr la imagen y el stack local | La imagen trae tres binarios: motor (el servicio), migrate y motorctl. |
| Postgres | Todo lo aceptado: comandos, ledger, entregas, sesiones de WhatsApp | Una base y un rol propios del motor. Se probó con Postgres 17. |
| MinIO | La multimedia (opcional) | Sin almacenamiento, la multimedia queda deshabilitada (503 multimedia_deshabilitada) y el resto funciona igual. |
| Salida a internet | La conexión con WhatsApp | Solo de salida. Un proxy de transporte por instancia es opcional. |
La conversión de medios (nota de voz, sticker, GIF) usa ffmpeg y ffprobe, que ya vienen en la
imagen. La imagen corre como usuario no root y está pensada para un contenedor de solo lectura,
con /tmp en memoria y /respaldos como volumen.
Las cuatro variables de entorno
Sección titulada «Las cuatro variables de entorno»El motor lee solo estas cuatro variables. No hay archivo de configuración: todo lo demás se guarda en la base y se edita en Ajustes.
| Variable | Obligatoria | Qué es |
|---|---|---|
DATABASE_URL |
Sí | La conexión a Postgres, por ejemplo postgres://motor:CLAVE@postgres:5432/motor_whatsapp?sslmode=disable. |
APP_MASTER_KEY |
Sí, para motor |
De 32 caracteres o más. Sella los secretos de Ajustes y los payloads del ledger, y de ella derivan los HMAC de las API keys, las sesiones y el CSRF. |
APP_ENV |
No | produccion (por omisión) o desarrollo. En desarrollo las cookies del panel van sin Secure, para entrar por http local. |
PORT |
No | El puerto HTTP. Por omisión, 8080. |
Genera la clave maestra una vez y guárdala en el gestor de secretos de tu infraestructura:
openssl rand -base64 48Si falta una variable o tiene un valor inválido, el motor no arranca y dice cuál, por ejemplo:
APP_MASTER_KEY debe tener al menos 32 caracteres o PORT debe ser un número entre 1 y 65535.
migrate y motorctl no necesitan APP_MASTER_KEY.
Levantar el stack local
Sección titulada «Levantar el stack local»El repositorio trae deploy/compose.local.yml: Postgres, MinIO, el paso de migraciones y el
motor, todos publicados solo en 127.0.0.1.
export APP_MASTER_KEY="$(openssl rand -base64 48)"docker compose -f deploy/compose.local.yml up --build -d| Servicio | Qué hace | Puerto local |
|---|---|---|
postgres |
La base del motor | 55432 (MOTOR_POSTGRES_PORT) |
minio |
El almacenamiento de la multimedia | 59000 (MOTOR_MINIO_PORT) |
migrate |
Corre migrate todo y termina |
— |
motor |
El servicio, cuando migrate terminó bien |
8080 (MOTOR_PORT) |
Las variables MOTOR_*_PORT son del compose, no del motor: solo cambian el puerto publicado. Los
servicios no se reinician solos (restart: "no"): lo que levantas, lo bajas tú.
Las migraciones
Sección titulada «Las migraciones»El motor tiene dos juegos de tablas, y se migran por separado:
- Las propias (goose):
migrate up. El motor también aplica las pendientes al arrancar, bajo un lock, antes de aceptar conexiones. - El store de whatsmeow (las sesiones de WhatsApp):
migrate whatsmeow. El motor no lo migra solo: si el store no está al día, el motor atiende la API pero sin transporte, y/health/readyresponde 503.
migrate todo hace las dos cosas; es lo que corre el compose antes del motor. Fuera del compose,
córrelo con la misma DATABASE_URL antes de arrancar motor:
docker run --rm -e DATABASE_URL="$DATABASE_URL" --entrypoint /app/migrate IMAGEN_DEL_MOTOR todo| Comando | Qué hace |
|---|---|
migrate up |
Aplica las migraciones propias pendientes. |
migrate status, migrate version |
Muestran el estado de las propias. |
migrate whatsmeow |
Actualiza el store de whatsmeow, bajo un advisory lock. |
migrate todo |
up y whatsmeow. |
migrate verificar |
La verificación previa a una actualización: lo pendiente, el store, el último backup y el modo. |
migrate down |
Revierte la última propia. Solo con APP_ENV=desarrollo. |
No hay down del store de whatsmeow: volver atrás una versión del SDK es restaurar un backup. Si
la base es más nueva que el binario (otra versión ya la migró), el motor no arranca y migrate up
no toca nada.
Crear el primer operador
Sección titulada «Crear el primer operador»Los operadores entran al panel con su correo y su contraseña. El primero se crea con motorctl
dentro del contenedor. La contraseña va por la entrada estándar, nunca como argumento ni como
variable:
# Con terminal: la pide dos veces sin mostrarla.docker compose -f deploy/compose.local.yml exec motor \ /app/motorctl operador crear --email tu@correo.com --nombre "Tu nombre"
# Sin terminal (un script): lee la primera línea de la entrada estándar.printf '%s\n' "$CONTRASENA" | docker compose -f deploy/compose.local.yml exec -T motor \ /app/motorctl operador crear --email tu@correo.com --nombre "Tu nombre"El rol por omisión es superadmin, el que puede crear apps, emitir keys y guardar Ajustes. Con
--rol operador creas uno que opera instancias pero no administra credenciales. Otros comandos
útiles:
| Comando | Qué hace |
|---|---|
motorctl operador listar |
Los operadores, con su rol y su estado. |
motorctl operador revocar-sesiones --email … |
Cierra todas las sesiones abiertas de un operador. |
motorctl diagnostico |
Versión, base, migraciones, conteos y store de whatsmeow, sin secretos ni datos personales. |
Entrar al panel
Sección titulada «Entrar al panel»Abre http://127.0.0.1:8080/admin/ y entra con el correo y la contraseña del operador. En el
mismo puerto están la referencia interactiva de la API (/docs) y el contrato
(/openapi.json).
- Con
APP_ENV=produccionla cookie de sesión llevaSecure: sirve el panel por HTTPS dentro de tu red (por ejemplo, detrás de un proxy inverso interno). - Tras 5 intentos fallidos en 15 minutos (por correo y por IP), el acceso responde 429 con
Retry-After. La sesión dura 12 horas. Los dos valores se cambian en Ajustes → Seguridad.
Qué hay en cada pantalla, en Panel de operadores.
Comprobar que está sano
Sección titulada «Comprobar que está sano»| Ruta o comando | Qué dice |
|---|---|
GET /health/live |
El proceso responde. |
GET /health/ready |
La base responde y el esquema está al día. 503 si falta migrar algo o la base es más nueva que el binario. |
motor salud |
El healthcheck del contenedor: pide /health/ready al propio proceso (la imagen no tiene curl). |
motorctl diagnostico |
El detalle, para un ticket: no muestra secretos ni datos personales. |
Todo lo demás va en Ajustes
Sección titulada «Todo lo demás va en Ajustes»Con el operador creado, termina de configurar el motor en Ajustes. Los secretos (claves de S3, tokens) se guardan sellados y nunca vuelven a mostrarse: el panel solo dice si hay uno.
| Grupo | Lo primero que conviene revisar |
|---|---|
| Almacenamiento (MinIO) | Endpoint, bucket (el motor lo crea privado si no existe), clave de acceso y clave secreta. Probar comprueba lo guardado. En el compose local: endpoint http://minio:9000, usuario motor-local y la clave de MOTOR_MINIO_CLAVE del compose. |
| Webhooks | Los destinos permitidos globales: los hosts a los que cualquier app puede entregar. Cada app suma los suyos. |
| Límites | El cupo de instancias por app (3 de fábrica), el ritmo de envío por instancia (1 mensaje por segundo, ráfaga de 2) y la cola de envíos (200). |
| Retención e historial | Cuánto se guarda lo entregado (30 días) y si se importan los mensajes del historial al vincular (apagado de fábrica). |
| Backups | El backup diario cifrado (apagado de fábrica). |
Los límites completos están en Cuotas y límites.
Revisar la interfaz sin WhatsApp
Sección titulada «Revisar la interfaz sin WhatsApp»Para mirar el panel sin vincular un número real, el motor tiene un proveedor falso que nunca
se conecta a WhatsApp. Solo arranca con APP_ENV=desarrollo:
docker compose -f deploy/compose.local.yml -f deploy/compose.falso.yml up --build -dBajar el stack
Sección titulada «Bajar el stack»docker compose -f deploy/compose.local.yml down # conserva la base y la multimediadocker compose -f deploy/compose.local.yml down -v # borra los volúmenesSiguiente paso
Sección titulada «Siguiente paso»Con el panel abierto, crea la app y su key. El recorrido completo, en cinco pasos, está en el Inicio rápido.