Instalação GenieACS: Bare Metal x Docker
Toda vez que alguém pergunta “como eu subo GenieACS?”, a conversa divide em dois times. De um lado: bare metal: Node, Mongo, systemd, serviço na máquina. Do outro: Docker: compose up e o stack aparece.
Os dois caminhos são válidos. O erro é tratar como religião. Eu uso os dois: bare metal quando quero controle fino (ou bater de frente com o mesmo modelo de produção sem container); Docker quando o objetivo é lab, turma e repetibilidade: e aí o roteador virtual entra de brinde.
Este post compara os dois com o que eu já validei na prática: script de instalação em Ubuntu/Debian (GenieACS 1.2.16 + Mongo + systemd) e o lab em Docker Compose (GenieACS + Mongo + CPE virtual).
O que a comunidade costuma bater
Bare metal, a favor: você vê o processo no systemctl, o log em arquivo, o npm global, o Mongo “de verdade” no host. Quem já opera ISP sem Docker se sente em casa. Menos uma camada na hora de debugar “por que a porta não abre”.
Bare metal, contra: instalação mais longa. Node na versão certa, Mongo que às vezes não sobe (kernel novo × pacote apt), quatro units systemd, permissão de usuário de sistema. Em turma, isso come tempo de aula.
Docker, a favor: mesmo stack para todo mundo. Sobe em minutos. Derruba e sobe de novo sem ritual. No lab que eu uso no curso, o CPE virtual já vem no compose: dá para treinar Inform, preset, provision e Connection Request sem depender de CPE físico na mesa.
Docker, contra: tem gente que não confia em ACS “dentro de container” para produção (persistência, update, backup, mental model). Fair. Outro ponto chato: misturar IP do host com serviço no container (hairpin NAT) quebra Connection Request se você inventar URL pública para o CPE no mesmo host. No lab, o caminho certo é a rede interna do Compose.
Minha leitura de engenheiro: para aprender e ensinar, Docker ganha no custo/benefício. Para entender o serviço nativo ou espelhar um VPS sem Docker, bare metal ainda faz sentido, e o script tira boa parte da dor.
preencha uma vez · Copiar já sai pronto · clique no token para voltar
IP público: curl ifconfig.me
Comparativo rápido
| Bare metal | Docker (lab) | |
|---|---|---|
| Tempo até UI | Maior (deps + systemd) | Menor (compose up) |
| Stack | GenieACS + Mongo no host | GenieACS + Mongo + CPE virtual (+ proxy NBI / dashboard no pacote do curso) |
| CPE para treinar | Você leva o seu | Virtual CPE incluso |
| Operação | systemctl / logs em arquivo |
docker compose logs / volumes |
| Melhor para | VPS “clássico”, estudo do serviço nativo | Lab, turma, demos, treino de fluxo TR-069 |
Caminho 1: Bare metal (Ubuntu/Debian)
O instalador sobe GenieACS 1.2.16 via npm install -g, prepara Mongo (apt ou bundle) e cria units systemd: cwmp, nbi, fs, ui. Diretório padrão: /opt/genieacs. Portas clássicas: UI 3000, CWMP 7547, NBI 7557, FS 7567.
Testado com foco em Ubuntu 22.04/24.04. Exige root no modo sistema (tem modo local para teste em 127.0.0.1).
Scripts bare metal estão no Diretório → Scripts. Links diretos:
- install-genieacs-bare.sh — instalador
- validate-genieacs-bare.sh — validação pós-install
- repair-genieacs-bare.sh — reparo após update do sistema
curl -fsSL https://www.mauroalexandre.com.br/wp-content/uploads/mauro-diretorio/install-genieacs-bare.sh -o install-genieacs-bare.sh
chmod +x install-genieacs-bare.sh
sudo ./install-genieacs-bare.sh
O que o script faz (em etapas)
Não é um “one-liner mágico”. A ordem importa, e é útil saber onde olhar quando algo falha no meio.
- Detecta o Ubuntu e avisa se não for 22.04/24.04 (Debian costuma rodar, mas o teste oficial foi Ubuntu).
- Pergunta o básico (ou lê env em modo não interativo): diretório, IP de escuta, portas, senha do Mongo, se quer proteger a NBI com nginx + Basic Auth.
- Instala Node se o host ainda não tiver
npmusable. - Sobe o Mongo: tenta apt; se o kernel for recente demais (6.19+) e o pacote quebrar, cai para bundle em
/opt/genieacs/mongodb. Sem esse fallback você fica caçando “mongod não sobe” sem motivo aparente. - Instala GenieACS 1.2.16 com
npm install -g genieacs@1.2.16. - Escreve o env em
/opt/genieacs/genieacs.env(portas, JWT, connection string, logs). - Cria e habilita systemd:
genieacs-cwmp,genieacs-nbi,genieacs-fs,genieacs-ui(prefixo configurável). - Opcional: nginx na frente da NBI com Basic Auth (NBI “pública” numa porta, processo GenieACS numa porta interna).
- Smoke test: espera HTTP na UI/NBI e TCP em CWMP/FS antes de declarar sucesso.
No topo do script você vê as variáveis padrão: dá para pré-setar e rodar sem prompt:
INSTALL_DIR=/opt/genieacs
UI_PORT=3000
CWMP_PORT=7547
NBI_PORT=7557
FS_PORT=7567
BIND_IP=0.0.0.0
GENIEACS_VERSION=1.2.16
Exemplo não interativo (útil em automação):
sudo GENIEACS_NON_INTERACTIVE=1
GENIEACS_UI_PORT=3000
GENIEACS_CWMP_PORT=7547
./install-genieacs-bare.sh
Quer mudar porta no ferro? Ou passa no prompt, ou edita /opt/genieacs/genieacs.env e reinicia as units. O validate lê esse arquivo. Se você mudar só o systemd e esquecer o env, a checagem aponta o descompasso.
Depois da instalação:
curl -fsSL https://www.mauroalexandre.com.br/wp-content/uploads/mauro-diretorio/validate-genieacs-bare.sh -o validate-genieacs-bare.sh
chmod +x validate-genieacs-bare.sh
sudo ./validate-genieacs-bare.sh
Se algo quebrou após update de sistema (Mongo/kernel/units):
curl -fsSL https://www.mauroalexandre.com.br/wp-content/uploads/mauro-diretorio/repair-genieacs-bare.sh -o repair-genieacs-bare.sh
chmod +x repair-genieacs-bare.sh
sudo ./repair-genieacs-bare.sh
O repair só reempacota o que precisa: seta GENIEACS_REPAIR=1, pula npm e força Mongo em modo bundle: não é “reinstalar do zero por diversão”.
Operação do dia a dia:
systemctl status genieacs-ui genieacs-cwmp genieacs-nbi genieacs-fs
journalctl -u genieacs-cwmp -f
Extensões (scripts JS do GenieACS) ficam em /opt/genieacs/ext.
CPE: aqui você aponta o ACS do roteador real (ou de outro lab) para http://SEU_IP:7547/. Bare metal não traz CPE virtual: é ACS no ferro.
Caminho 2: Docker (lab com CPE virtual)
O pacote de lab é um Compose: Mongo 7 + GenieACS 1.2.16 + virtual-cpe (painel + Connection Request) + proxy da NBI + dashboard didático. A ideia é editar só o IP e subir. Resto do stack já nasce alinhado.
Pacote no Diretório → Scripts:
- tr069-lab.tar.gz — lab Docker completo (GenieACS + CPE virtual)
Passo a passo
sudo mkdir -p /opt
cd /opt
curl -fsSL https://www.mauroalexandre.com.br/wp-content/uploads/mauro-diretorio/tr069-lab.tar.gz -o tr069-lab.tar.gz
sudo tar -xzf tr069-lab.tar.gz
sudo chown -R "$USER":"$USER" /opt/tr069-lab
cd /opt/tr069-lab
# .env já vem no tarball — edite só o IP
nano .env
No .env, a linha que importa primeiro:
LAB_PUBLIC_IP=SEU_IP
Cole o mesmo valor da caixa SEU_IP acima (sem http://). Esse valor alimenta a URL do ACS no painel do CPE virtual. Se ficar placeholder, o painel mostra URL inútil e o Inform não sobe do jeito certo.
Subir:
docker compose up --build -d
docker compose ps
Uso pedagógico mínimo:
- UI GenieACS:
http://SEU_IP:3000(lab:admin/admin) - Painel do roteador virtual:
http://SEU_IP:8080 - ACS URL no CPE:
http://SEU_IP:7547/→ salvar e conectar - Voltar na UI, device após o primeiro Inform
- Rodar o seed do curso e testar Connection Request / preset / provision
docker compose logs -f virtual-cpe
docker compose logs -f genieacs
./scripts/seed-curso.sh
Portas no .env (e o que muda se você alterar)
O compose lê o host a partir do .env. Padrão do lab:
GENIEACS_UI_PORT=3000
GENIEACS_CWMP_PORT=7547
GENIEACS_NBI_PORT=7557
GENIEACS_FS_PORT=7567
VIRTUAL_CPE_PORT=8080
VIRTUAL_CPE_CR_PORT=7548
Exemplo: a 3000 já está ocupada no seu VPS. Mude só o mapeamento do host:
GENIEACS_UI_PORT=3001
Reinicie o serviço afetado (ou o stack):
docker compose up -d
# UI agora: http://SEU_IP:3001
Importante: a porta dentro do container do GenieACS continua 3000/7547/…. O que muda no .env é a porta no host (HOST:CONTAINER). No docker-compose.yml isso aparece assim:
ports:
- "${GENIEACS_CWMP_PORT:-7547}:7547"
- "${GENIEACS_FS_PORT:-7567}:7567"
- "${GENIEACS_UI_PORT:-3000}:3000"
Se você mudar GENIEACS_CWMP_PORT=8547, o CPE (e qualquer roteador real apontando para esse lab) precisa usar http://SEU_IP:8547/: não 7547.
Mesma lógica no painel do virtual CPE: VIRTUAL_CPE_PORT=8080 → se mudar para 8088, o browser vai em http://SEU_IP:8088.
Mexer no Compose (além do .env)
Na maioria das aulas, não precisa editar o YAML. Quando precisa:
- Tirar um serviço (ex.: dashboard), comente o bloco
dashboard:no compose ou use um override. - Só GenieACS + Mongo (sem CPE virtual), dá, mas aí você volta a depender de CPE físico; o valor do lab some.
- Persistência: volumes
mongo_data,genieacs_ext,cpe_data.docker compose downmantém volumes;down -vapaga dados do lab. - NBI com Basic Auth na aula de segurança: no
.env,NBI_AUTH_ENABLED=true+ user/pass. Quem expõe a 7557 é onbi-proxy, não o GenieACS direto. Por isso dá para ligar auth sem rebuild da imagem do ACS.
Override rápido (arquivo docker-compose.override.yml ao lado do compose) se quiser, por exemplo, publicar a UI só em localhost:
services:
genieacs:
ports:
- "127.0.0.1:3000:3000"
Depois: docker compose up -d. O override mescla com o arquivo principal.
Connection Request no lab
ACS e CPE virtual estão no mesmo Compose. O ACS acorda o CPE pelo hostname interno (virtual-cpe), não pelo IP público do host. Se você forçar URL pública para o CR no mesmo servidor, cai no hairpin NAT e o Summon “não responde”. Em produção o CR é o IP/rota do CPE de verdade; lab é outro desenho, de propósito.
Teste manual de CR (de dentro da rede Docker):
docker compose exec genieacs wget -q -O- --user=acs --password=acs
http://virtual-cpe:7548/tr069/connection-request
NBI no lab pode começar aberta (aula) e ganhar Basic Auth no proxy quando o tema for segurança. Não misture isso com a senha de ACS username do CPE: são mundos diferentes.
Quando eu escolho cada um
- Turma, demo, treino de Inform/preset/CR sem CPE na mesa → Docker + virtual CPE.
- VPS de estudo “sem Docker”, ou quero ver systemd/npm/Mongo no host → bare metal com o script.
- Produção → aí a conversa muda: backup do Mongo, exposição de portas, auth da NBI, TLS na frente, atualização. Docker ou bare metal deixam de ser “gosto” e viram política de operação. O lab não é atalho para produção irrefletida.
Armadilhas comuns (os dois lados)
- Porta 3000/7547/8080 já ocupada, confira com
ss -tlnp | grep -E '3000|7547|8080'antes de culpar o GenieACS. - Device não aparece: URL do ACS errada no CPE (IP/porta/barra final) ou firewall comendo 7547.
- Docker:
LAB_PUBLIC_IP/SEU_IPesqueceu de setar, o painel do CPE virtual mostra URL inútil. Use a caixa no topo oucurl ifconfig.me. - Bare metal: Mongo apt vs kernel, use o caminho bundle quando o script indicar.
- NBI aberta na internet sem auth = convite. Lab ok; produção não.
Fechando
Se a meta é ver Inform na UI sem ficar horas pelejando com Node e Mongo, sobe o Docker com o CPE virtual. Se a meta é entender o que o systemd está fazendo e onde o env mora no disco, usa o bare metal: o script só evita você digitar a mesma sequência errada três vezes.
No meu dia a dia de lab e turma, eu começo no Compose. Quando alguém pergunta “e em produção sem container?”, aí a gente abre o script e olha unit por unit.
Se algo não bater no seu lab, deixa um comentário no post.
Gostou do conteúdo? Veja os cursos em aberto ou entre na lista de interesse. Os treinamentos são ao vivo e 100% práticos.