Ir al contenido
angel.library

OpenWA — instalación y despliegue

RequisitoVersión
Node.js>=22.13 (solo para instalación local)
Docker + Docker ComposeRecomendado para cualquier uso serio
ChromiumLo instala la imagen; solo hace falta a mano en local con el motor whatsapp-web.js

Es la vía recomendada. La configuración se genera sola en el primer arranque.

Ventana de terminal
git clone https://github.com/rmyndharis/OpenWA.git
cd OpenWA
docker compose -f docker-compose.dev.yml up -d

Al terminar, el panel queda en http://localhost:2785.

El compose de desarrollo usa SQLite y almacenamiento local, y la API sirve el panel ya empaquetado dentro de la misma imagen.

Útil para leer el código o contribuir, no para producción.

Ventana de terminal
git clone https://github.com/rmyndharis/OpenWA.git
cd OpenWA
npm ci
npm run dev

npm ci instala exactamente las versiones del lockfile, incluido el panel. Usa npm install solo cuando quieras cambiar dependencias a propósito.

En modo desarrollo el panel corre aparte, en el servidor de Vite con recarga en caliente, así que son dos puertos distintos.

ServicioPuertoNota
API y panel2785En Docker van juntos en el mismo puerto
Swagger2785/api/docsSe apaga con NODE_ENV=production salvo que pongas ENABLE_SWAGGER=true
Panel en desarrollo2886Solo con npm run dev

El docker-compose.yml principal trae perfiles para encender servicios opcionales:

Ventana de terminal
docker compose up -d
Ventana de terminal
docker compose --profile postgres up -d
Ventana de terminal
docker compose --profile full up -d
PerfilLevanta
postgresBase de datos PostgreSQL
redisCaché Redis
minioAlmacenamiento compatible con S3
fullLos tres anteriores

El panel no necesita perfil: viaja dentro de la imagen de la API y se sirve donde corra openwa-api.

Las imágenes oficiales se publican en GHCR como manifiestos multiarquitectura para linux/amd64 y linux/arm64.

OpenWA no termina TLS por su cuenta. Para exponerlo hay que poner delante un proxy inverso propio: nginx, Caddy, un balanceador del proveedor o un Ingress de Kubernetes.

Casi todo se cambia por configuración, no tocando código:

PiezaOpciones
Motor de WhatsAppwhatsapp-web.js (por defecto) o baileys, con ENGINE_TYPE
Base de datosSQLite o PostgreSQL
CachéDesactivada o Redis
AlmacenamientoLocal o S3/MinIO

Un detalle que conviene saber: el contenido multimedia se devuelve en línea a quien consume la API y los webhooks. No se guarda automáticamente en el backend de almacenamiento —ese backend es para respaldo y migración—.

Dos decisiones del proyecto que vale la pena conocer antes de exponerlo:

El socket de Docker no se monta directo. La aplicación habla con un contenedor intermediario (docker-socket-proxy) que solo habilita las operaciones necesarias:

openwa-api ──TCP 2375──▶ docker-proxy ──unix──▶ /var/run/docker.sock

El propio proyecto aclara que esto es una puerta de enlace operativa, no una frontera de privilegios fina: con POST habilitado, un contenedor de API comprometido equivale a root en el host. El modelo de amenazas completo está en su SECURITY.md.

El proceso de Node no corre como root. El arranque baja privilegios en cadena:

dumb-init (PID 1)
└─ docker-entrypoint.sh (root, solo para corregir permisos del volumen)
└─ gosu openwa node dist/main

En modo rootless hace falta el socket activo y la variable DOCKER_HOST:

Ventana de terminal
systemctl --user start podman.socket
systemctl --user enable podman.socket
export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock

Conviene dejar el export en ~/.bashrc para que sobreviva a la sesión.

Con el servicio arriba, el flujo de crear sesión, escanear el QR y enviar mensajes está en OpenWA — sesiones y mensajes.