Des déploiements séparés sur un seul hôte — un par client, ou un par environnement. Ce n’est pas
un cluster : ce sont des passerelles indépendantes avec leurs propres bases de données et leur
propre trafic. Pour comprendre pourquoi plusieurs instances contre une seule base de données ne
fonctionnent pas, voir Clustering.
Un nom, deux produits
--tenant est toute l’idée : le même mot nomme la même instance aux deux installateurs. Un nom
par client, deux produits.
À la mise à jour, c’est une recherche, pas une disposition
C’est la partie qui évite l’erreur coûteuse.
Sur update, service et rollback, --tenant trouve l’installation portant ce nom et
utilise ses propres chemins, unité, compte et ports.
Sans cela, une mise à niveau visée en oubliant un drapeau arrêterait une unité qui pourrait ne pas
exister, remplacerait un répertoire appartenant à une autre instance, et activerait un second
service contre la même base de données.Une unité dont le WorkingDirectory= nomme une installation différente est refusée, avant que
quoi que ce soit ne soit arrêté.
Ports
Donnez une plage et l’installateur prend le prochain port d’écoute libre, de sorte que l’instance
deux ne rentre pas en collision avec l’instance un. --http-port et --ops-port sont également
définis par instance.
Les deux installateurs relisent les ports depuis le fichier d’environnement sur update, de sorte
qu’une instance sur des ports non par défaut cesse d’échouer sa propre vérification à la fin de
chaque mise à niveau.
Un hôte virtuel
Place l’instance sous un dossier personnel par client : /home/websmsc/gateway, avec le panneau à
/home/websmsc/panel.
Ce que cela apporte : les deux unités générées montent un tmpfs sur /home et ne
réintroduisent que ce seul hôte virtuel, de sorte qu’une passerelle ne peut voir aucun autre
répertoire personnel client.
--user est requis ici, et c’est l’étape la plus facile à oublier. Un répertoire personnel est
en 0750 et appartient à son propre compte, et l’installateur ne fera pas de chown sur un
répertoire qui existe déjà — cette protection est délibérée, afin qu’une installation ne puisse
jamais réécrire la propriété de tout ce qui se trouve déjà dans le dossier personnel de quelqu’un.Ainsi, un service tournant sous n’importe quel autre compte ne peut tout simplement pas traverser
l’hôte virtuel. ProtectHome=tmpfs et BindPaths= rendent le répertoire visible à l’intérieur
de l’espace de noms de l’unité ; aucun des deux ne modifie un bit de permission.Le symptôme ne nomme pas la cause : le panneau meurt à npm ci avec can't cd to /home/<nom>/panel/app, et la passerelle enregistre une unité qui ne peut ensuite pas lire sa
propre configuration. Passez le compte propriétaire aux deux installateurs.
Sous --vhost, CDR_EXPORT_DIR du panneau doit également se trouver à l’intérieur d’une racine
BindPaths=. Cet échec est silencieux — les exports sont préparés puis ne peuvent pas être lus.
--vhost seul, sans --tenant, signifie quelque chose de différent — ne l’utilisez pas pour un
nouveau tenant. Cela conserve une ancienne disposition à plat, CHEMIN/{app,conf,data}, au lieu
de CHEMIN/panel.Cette compatibilité existe pour que les panneaux installés sous /home/<nom> avant --tenant
soient atteints exactement comme avant, et qu’une mise à niveau ne relocalise jamais une
installation en cours d’exécution. Sur un nouveau tenant, cela place silencieusement la passerelle
et le panneau dans des dispositions différentes — la passerelle sous /srv/fireflo/<nom>/gateway
et le panneau libre dans /home/<nom> — après quoi update --tenant <nom> ne trouve plus le
panneau. Passez les deux drapeaux ensemble.
Les trois drapeaux de répertoire — --app-dir, --conf-dir, --data-dir — l’emportent toujours
sur l’un ou l’autre schéma partout où ils sont donnés.
Ce dont chaque instance a besoin en propre
Suppression d’un tenant
Il n’existe pas de verbe uninstall. Les deux installateurs offrent check, install,
update, service et rollback — la suppression est manuelle, ce qui explique pourquoi il vaut
mieux énumérer les unités que de les deviner.
Un tenant, c’est quatre unités systemd, pas deux. La passerelle en écrit trois :
Le timer logclean est celui qui reste oublié derrière. Supprimez uniquement l’unité principale
et il reste activé, se déclenchant chaque jour sur un répertoire de journaux qui n’existe plus.
Regardez avant de supprimer — ceci ne change rien :
Ensuite les unités, toutes les quatre :
Ensuite les répertoires — selon la disposition qu’a utilisée ce tenant :
Loaded: not-found aux côtés de Active: failed est normal ici, ce n’est pas une anomalie.
C’est la mémoire d’exécution de systemd d’une unité dont le fichier a disparu ; reset-failed la
nettoie. De même, un code de sortie status=143 dans le journal, c’est 128 + SIGTERM — un arrêt
propre, pas un plantage.
Ce que cela laisse délibérément intact
La base de données. Le routage d’un tenant, ses fournisseurs, ses ports d’écoute, ses
identifiants, ses enregistrements d’appels et ses soldes y résident, pas dans le répertoire
d’installation — c’est ce qui rend une réinstallation sûre, et ce qui fait de la suppression de la
base de données une décision distincte :
Le compte de service, qui peut être partagé avec d’autres services ou être un véritable
identifiant client. Supprimez-le à la main seulement une fois certain que rien d’autre ne l’utilise.
Les règles de pare-feu, si l’installation a utilisé --firewall. Vérifiez
sudo ufw status numbered pour la plage SMPP et le port HTTP de ce tenant.
Réinstaller plutôt que supprimer
Relocaliser une instance n’est pas un mv. fireflo.env enregistre ses propres chemins absolus,
et seuls certains sont réécrits par des verbes ultérieurs — FIREFLO_CONF_DIR, FIREFLO_DATA_DIR
et QUARKUS_LOG_FILE_PATH sont écrits par install uniquement. Une installation déplacée continue
d’écrire ses enregistrements d’appels et ses journaux à l’ancien emplacement, tandis que le
ReadWritePaths= de la nouvelle unité ne couvre que le nouveau.
Supprimez et réinstallez à la place. La base de données survit, donc la nouvelle installation
omet --bootstrap — celle-ci refuse de s’exécuter sur une base de données qui possède déjà une
table de routage, un worker ou un identifiant.