Implantações separadas em um mesmo host — uma por cliente, ou uma por ambiente. Não é um cluster:
são gateways independentes com seus próprios bancos de dados e seu próprio tráfego. Para saber por que
várias instâncias contra um mesmo banco não funcionam, veja
Clustering.
Um nome, dois produtos
--tenant é a ideia inteira: a mesma palavra nomeia a mesma instância para ambos os instaladores.
Um nome por cliente, dois produtos.
Na atualização é uma busca, não um layout
Esta é a parte que evita o erro caro.
Em update, service e rollback, --tenant encontra a instalação com aquele nome e usa seus
próprios caminhos, unidade, conta e portas.
Sem isso, uma atualização direcionada por esquecer uma flag poderia parar uma unidade que talvez nem
exista, substituir um diretório pertencente a outra instância e habilitar um segundo serviço contra o
mesmo banco de dados.Uma unidade cujo WorkingDirectory= aponte para uma instalação diferente é recusada, antes que
qualquer coisa seja parada.
Portas
Dê uma faixa e o instalador pega a próxima porta de listener livre, para que a instância dois não
colida com a instância um. --http-port e --ops-port também são definidos por instância.
Ambos os instaladores leem as portas de volta do arquivo de ambiente no update, para que uma
instância em portas não-padrão pare de falhar no seu próprio verify ao final de cada atualização.
Um virtualhost
Coloca a instância sob um home por cliente: /home/websmsc/gateway, com o painel em
/home/websmsc/panel.
O que isso traz: ambas as unidades geradas montam um tmpfs sobre /home e fazem bind apenas
daquele virtualhost específico, de modo que um gateway não consegue enxergar o diretório home de
nenhum outro cliente.
--user é obrigatório aqui, e é a etapa mais fácil de esquecer. Um diretório home é 0750 e
pertence à sua própria conta, e o instalador não fará chown de um diretório que já existe — essa
proteção é deliberada, para que uma instalação jamais reescreva a propriedade de tudo o que já está
no home de alguém.Então um serviço rodando com qualquer outra conta simplesmente não consegue atravessar o virtualhost.
ProtectHome=tmpfs e BindPaths= tornam o diretório visível dentro do namespace da unidade;
nenhum dos dois muda um bit de permissão.O sintoma não nomeia a causa: o painel morre no npm ci com can't cd to /home/<name>/panel/app, e
o gateway registra uma unidade que depois não consegue ler sua própria configuração. Passe a conta
proprietária para ambos os instaladores.
Sob --vhost, o CDR_EXPORT_DIR do painel também deve estar dentro de uma raiz BindPaths=. Essa
falha é silenciosa — exportações são preparadas e depois não podem ser lidas.
--vhost sozinho, sem --tenant, significa outra coisa — não use para um novo tenant. Ele
preserva um layout plano mais antigo, PATH/{app,conf,data}, em vez de PATH/panel.Essa compatibilidade existe para que painéis instalados sob /home/<name> antes de --tenant sejam
alcançados exatamente como antes, e para que uma atualização nunca realoque uma instalação em
execução. Em um tenant novo isso silenciosamente coloca o gateway e o painel em layouts diferentes
— o gateway em /srv/fireflo/<name>/gateway e o painel solto em /home/<name> — depois disso o
update --tenant <name> não encontra mais o painel. Passe as duas flags juntas.
As três flags de diretório — --app-dir, --conf-dir, --data-dir — ainda prevalecem sobre qualquer
esquema em que forem fornecidas.
O que cada instância precisa ter só para si
Removendo um tenant
Não existe um verbo uninstall. Ambos os instaladores oferecem check, install, update,
service e rollback — a remoção é manual, e é por isso que vale a pena enumerar as unidades em
vez de tentar adivinhá-las.
Um tenant são quatro unidades systemd, não duas. O gateway grava três:
O timer de logclean é o que costuma ficar para trás. Se você remover apenas a unidade principal,
ele permanece habilitado, disparando todo dia contra um diretório de logs que não existe mais.
Olhe antes de remover — isto não muda nada:
Depois as unidades, todas as quatro:
Depois os diretórios — qualquer que seja o layout que esse tenant tenha usado:
Loaded: not-found junto com Active: failed é normal aqui, não é uma falha. É a memória de
tempo de execução do systemd de uma unidade cujo arquivo foi removido; reset-failed limpa isso.
Do mesmo modo, uma saída status=143 no journal é 128 + SIGTERM — uma parada limpa, não um crash.
O que isto deliberadamente deixa intocado
O banco de dados. O roteamento de um tenant, seus vendors, listeners, logins, registros de
chamadas e saldos vivem lá, não no diretório de instalação — e é isso que torna uma reinstalação
segura, e o que faz de descartar o banco uma decisão à parte:
A conta de serviço, que pode ser compartilhada com outros serviços ou ser um login real de
cliente. Remova-a manualmente somente depois de ter certeza de que nada mais a utiliza.
Regras de firewall, caso a instalação tenha usado --firewall. Verifique
sudo ufw status numbered procurando pela faixa SMPP e pela porta HTTP deste tenant.
Reinstalar em vez de remover
Realocar uma instância não é um mv. O fireflo.env registra seus próprios caminhos absolutos, e
apenas alguns são reescritos por verbos posteriores — FIREFLO_CONF_DIR, FIREFLO_DATA_DIR e
QUARKUS_LOG_FILE_PATH são gravados somente pelo install. Uma instalação movida continua
gravando seus registros de chamadas e logs no local antigo, enquanto o ReadWritePaths= da nova
unidade cobre apenas o novo.
Remova e reinstale em vez disso. O banco de dados sobrevive, então a instalação nova omite
--bootstrap — ele se recusa a rodar sobre um banco que já tem uma tabela de roteamento, um worker
ou um login.