Despliegues separados en un mismo host — uno por cliente, o uno por entorno. No es un clúster:
son gateways independientes con sus propias bases de datos y su propio tráfico. Para saber por qué
varias instancias contra una misma base de datos no funciona, consulta
Clustering.
Un nombre, dos productos
--tenant es toda la idea: la misma palabra nombra la misma instancia para ambos instaladores.
Un nombre por cliente, dos productos.
En una actualización es una búsqueda, no un diseño
Esta es la parte que evita el error caro.
En update, service y rollback, --tenant encuentra la instalación con ese nombre y usa sus
propias rutas, unidad, cuenta y puertos.
Sin eso, una actualización dirigida olvidando un flag pararía una unidad que puede no existir,
reemplazaría un directorio que pertenece a otra instancia y habilitaría un segundo servicio contra la
misma base de datos.Una unidad cuyo WorkingDirectory= nombre una instalación diferente es rechazada antes de detener
nada.
Puertos
Da un rango y el instalador toma el siguiente puerto de listener libre, para que la instancia dos no
choque con la uno. --http-port y --ops-port también se fijan por instancia.
Ambos instaladores leen los puertos del archivo de entorno en update, para que una instancia en
puertos no predeterminados deje de fallar su propio verify al final de cada actualización.
Un virtualhost
Coloca la instancia bajo un directorio personal por cliente: /home/websmsc/gateway, con el panel en
/home/websmsc/panel.
Qué se gana: ambas unidades generadas montan un tmpfs sobre /home y reintroducen únicamente
ese virtualhost, de modo que un gateway no puede ver el directorio personal de ningún otro cliente.
Aquí --user es obligatorio, y es el paso que más fácilmente se omite. Un directorio personal es
0750 y pertenece a su propia cuenta, y el instalador no cambia el propietario de un directorio
que ya existe — esa protección es deliberada, para que una instalación nunca reescriba la propiedad
de todo lo que ya haya en el directorio personal de alguien.Así que un servicio que se ejecute con cualquier otra cuenta simplemente no puede recorrer el
virtualhost. ProtectHome=tmpfs y BindPaths= hacen que el directorio sea visible dentro del
namespace de la unidad; ninguno cambia un bit de permisos.El síntoma no nombra la causa: el panel muere en npm ci con can't cd to /home/<name>/panel/app, y
el gateway registra una unidad que luego no puede leer su propia configuración. Pasa la cuenta
propietaria a ambos instaladores.
Bajo --vhost, CDR_EXPORT_DIR del panel también debe estar dentro de una raíz de BindPaths=.
Ese fallo es silencioso — las exportaciones se preparan y luego no se pueden leer.
--vhost solo, sin --tenant, significa otra cosa — no lo uses para un nuevo tenant. Mantiene
un diseño plano más antiguo, PATH/{app,conf,data}, en lugar de PATH/panel.Esa compatibilidad existe para que los paneles instalados bajo /home/<name> antes de --tenant se
alcancen exactamente como antes, y una actualización nunca reubique una instalación en ejecución. En
un tenant nuevo deja en silencio el gateway y el panel en diseños diferentes — el gateway en
/srv/fireflo/<name>/gateway y el panel suelto en /home/<name> — tras lo cual
update --tenant <name> ya no encuentra el panel. Pasa ambos flags juntos.
Los tres flags de directorio — --app-dir, --conf-dir, --data-dir — siguen prevaleciendo sobre
cualquier esquema dondequiera que se especifiquen.
Qué necesita cada instancia por su cuenta
Eliminar un tenant
No existe un verbo uninstall. Ambos instaladores ofrecen check, install, update, service
y rollback — la eliminación es manual, y por eso vale la pena enumerar las unidades en lugar de
intentar adivinarlas.
Un tenant son cuatro unidades systemd, no dos. El gateway escribe tres:
El timer de logclean es el que suele quedarse olvidado. Si eliminas solo la unidad principal,
sigue habilitado y se dispara todos los días contra un directorio de logs que ya no existe.
Mira antes de eliminar — esto no cambia nada:
Luego las unidades, las cuatro:
Después los directorios — cualquiera que sea el diseño que usó este tenant:
Loaded: not-found junto a Active: failed es normal aquí, no es un fallo. Es la memoria en
tiempo de ejecución que systemd guarda de una unidad cuyo archivo ha desaparecido; reset-failed la
limpia. De la misma forma, una salida status=143 en el journal es 128 + SIGTERM — una parada
limpia, no un crash.
Qué se deja intacto deliberadamente
La base de datos. El enrutamiento del tenant, los vendors, listeners, logins, registros de
llamadas y saldos viven ahí, no en el directorio de instalación — que es lo que hace segura una
reinstalación, y lo que convierte en una decisión aparte eliminar la base de datos:
La cuenta de servicio, que puede estar compartida con otros servicios o ser un login real de
cliente. Elimínala a mano solo cuando estés seguro de que nada más la usa.
Las reglas de firewall, si la instalación usó --firewall. Comprueba con
sudo ufw status numbered el rango SMPP y el puerto HTTP de este tenant.
Reinstalar en lugar de eliminar
Reubicar una instancia no es un mv. fireflo.env guarda sus propias rutas absolutas, y solo
algunas son reescritas por verbos posteriores — FIREFLO_CONF_DIR, FIREFLO_DATA_DIR y
QUARKUS_LOG_FILE_PATH los escribe únicamente install. Una instalación movida sigue escribiendo
sus registros de llamadas y logs en la ubicación antigua, mientras que el ReadWritePaths= de la
nueva unidad cubre solo la nueva.
Elimina y reinstala en su lugar. La base de datos sobrevive, así que la instalación nueva omite
--bootstrap — se niega a ejecutarse sobre una base de datos que ya tiene una tabla de enrutamiento,
un worker o un login.