Guia passo a passo — Parte 1: Instalar
Parte 1 do guia passo a passo: instalar o TWS Panel numa VPS limpa, do zero até o assistente de configuração (wizard). O README tem a versão curta; este guia explica cada passo, o que aparece na tela e o que fazer quando algo dá errado.
Os passos são numerados de 1 a 8. Os scripts do painel (install.sh, uninstall.sh) citam
esses números.
| Passo | Onde | O que faz |
|---|---|---|
| 1 | Provedor | Contratar a VPS |
| 2 | Seu computador → VPS | Entrar como root e conferir o sistema |
| 3 | VPS | Criar o seu usuário não-root |
| 4 | Seu computador | Gerar a chave SSH e instalar na VPS |
| 5 | VPS | Instalar o git |
| 6 | VPS | Clonar o repositório em /opt/tws-panel |
| 7 | VPS | Rodar o instalador |
| 8 | Navegador | Abrir o painel e seguir o wizard |
Depois do Passo 8, a etapa de Segurança do wizard tem um guia próprio: Wizard de segurança. Em seguida, a Parte 2 continua a configuração.
Antes de começar
Seção intitulada “Antes de começar”O que contratar
Seção intitulada “O que contratar”Uma VPS (servidor virtual) com:
- Ubuntu 22.04 ou 24.04 LTS, limpa (sem outros programas instalados). Na criação, prefira o 24.04.
- Mínimo recomendado: 1 vCPU, 2 GB de RAM e 25 GB de disco.
- Portas 80 e 443 abertas para a internet. O certificado HTTPS depende delas. Se o provedor tem um firewall no painel da hospedagem, libere as duas.
- Para o e-mail: a porta 25 liberada pelo provedor. Muitos provedores a bloqueiam, principalmente em contas novas. Você confere isso na Etapa 4 da Parte 2.
Você vai precisar de duas coisas que o provedor entrega: o IP da VPS e a senha de root. Antes de seguir, procure no painel do provedor por “Console”, “VNC”, “Rescue” ou “Modo de recuperação” e confirme que ele existe: é o caminho de volta se você perder o acesso SSH. Veja Perdi o acesso.
Domínio (opcional, mas recomendado)
Seção intitulada “Domínio (opcional, mas recomendado)”Sem domínio, tudo funciona com endereços automáticos *.sslip.io (por exemplo,
https://203-0-113-10.sslip.io). Com um domínio seu, você ganha:
- um endereço próprio para o painel (
painel.example.com), em vez de um com o IP no nome; - o e-mail profissional, que exige domínio;
- endereços próprios para os seus projetos.
Você vai criar registros no DNS do domínio (no provedor onde ele está, ou no Cloudflare). Os exemplos da Parte 2 usam o Cloudflare. Pode deixar o domínio para depois: nada na Parte 1 depende dele.
| Conta | Para quê | Obrigatória? |
|---|---|---|
| GitHub | Publicar projetos a partir de um repositório. Repositório privado pede um token somente leitura (a tela ensina a gerar). | Só se o código está no GitHub |
| Cloudflare | O R2, o armazenamento externo dos backups (o plano gratuito cobre 10 GB por mês; ele pede um cartão). Também serve de DNS do domínio. | Recomendada |
| Telegram | Receber os avisos do painel no celular. | Opcional |
Nenhuma delas é usada na Parte 1; você só precisa delas na Parte 2.
Reinstalou a VPS?
Seção intitulada “Reinstalou a VPS?”⚠️ Deu erro ao conectar: "REMOTE HOST IDENTIFICATION HAS CHANGED!"
Se, ao tentar conectar, apareceu isto em letras garrafais e a conexão foi recusada:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!...Host key verification failed.O que aconteceu. O SSH guarda a “digital” de cada servidor em que você já entrou. A digital que o servidor apresentou agora é diferente da que está guardada no seu computador — e o SSH prefere recusar a conexão a te conectar num servidor que pode não ser o seu.
Quando isso é esperado: você reinstalou o sistema da VPS, trocou de VPS, ou o provedor reatribuiu aquele mesmo IP a outra máquina. Nesses casos o servidor é outro de verdade, e a digital antiga não vale mais.
A solução — apague a digital antiga daquele IP e conecte de novo. Rode no seu computador:
ssh-keygen -R SEU_IPssh root@SEU_IPEle vai perguntar se você confia na nova identidade — responda yes. Pronto, a conexão volta ao
normal.
🔄 Já tinha o painel instalado e quer começar de novo?
Antes de reinstalar a máquina inteira, veja se o caso é mesmo esse — quase sempre não é.
Só quero refazer o assistente de configuração. Não precisa reinstalar nada. Na VPS:
cd /opt/tws-panelsudo ./scripts/reset-setup.sh # o wizard volta ao passo 0sudo ./scripts/show-token.sh # mostra o setup token de novoSeus projetos, domínios, e-mail e histórico de segurança continuam intactos. Use --full no
primeiro comando se quiser apagar também a conta de administrador do painel.
Quero remover o painel e instalar de novo, sem reinstalar o sistema. Serve para testar a instalação quantas vezes quiser. Na VPS:
cd /opt/tws-panel./scripts/uninstall.sh --dry-run # só mostra o que seria apagado; não mexe em nada./scripts/uninstall.sh # mostra de novo e pede para você digitar "remover"Ele apaga tudo o que o painel criou: o painel e os containers dele, o proxy (Caddy), o servidor
de e-mail, os projetos implantados com seus dados, a pasta /opt/tws-projects, os scripts de
hardening copiados para a VPS e, por último, a própria pasta /opt/tws-panel. Antes de apagar, ele
lista exatamente o que encontrou. Depois, entre em outra pasta (cd ~) e recomece pelo Passo 6
(clonar o repositório) — o git do Passo 5 continua instalado. Quer manter a pasta do repositório?
Use --keep-repo e vá direto ao Passo 7.
Quero a máquina limpa de verdade. Aí sim é reinstalação do sistema operacional, e ela acontece em dois lugares:
1. No painel do seu provedor de VPS. Procure por “Reinstall”, “Reimage” ou “Reinstalar sistema” — o nome muda conforme o provedor. Escolha Ubuntu 24.04 LTS e anote a nova senha de root que ele gerar; a antiga deixa de valer.
2. No seu computador. Como o sistema é outro, o servidor passa a se identificar com uma chave
diferente, e a sua próxima conexão vai ser recusada com o aviso
REMOTE HOST IDENTIFICATION HAS CHANGED!. Isso é esperado, e a solução está no bloco logo acima:
⬆️ Deu erro ao conectar: “REMOTE HOST IDENTIFICATION HAS CHANGED!”
Depois disso é só seguir do Passo 1 em diante, como numa VPS nova — porque agora ela é uma.
Passo 1 — Contrate uma VPS
Seção intitulada “Passo 1 — Contrate uma VPS”Contrate uma VPS com Ubuntu 24.04 LTS (mínimo recomendado: 1 vCPU / 2 GB RAM / 25 GB de disco), conforme os requisitos de Antes de começar.
Passo 2 — Acesse como root via SSH
Seção intitulada “Passo 2 — Acesse como root via SSH”Entre na VPS e confirme a versão do SO:
ssh root@SEU_IPcat /etc/os-release # esperado: PRETTY_NAME="Ubuntu 24.04.x LTS" (ou 22.04)🔐 Primeira vez conectando via SSH? O que aparece e o que responder
Na primeira conexão com qualquer servidor novo, o SSH mostra este aviso:
The authenticity of host '203.0.113.10 (203.0.113.10)' can't be established.ED25519 key fingerprint is SHA256:Xk9vN2mQpL7dR4wT8yB3cF6hJ1uA5sE0gH9zK2xW4vM.This key is not known by any other names.Are you sure you want to continue connecting (yes/no/[fingerprint])?O que responder: digite yes e pressione Enter.
O que é isso? O fingerprint é a “digital” do servidor — é assim que o seu computador reconhece a VPS nas próximas conexões. O aviso aparece só na primeira vez; depois o fingerprint fica salvo e a conexão é direta.
Erros comuns:
- “Digito a senha e nada aparece” — é normal! O terminal não mostra nenhum caractere
(nem
*) enquanto você digita senhas. Digite com calma e pressione Enter. Permission denied (publickey,password)— senha errada ou o provedor da VPS exige chave SSH. Confira a senha no painel do provedor e tente de novo.- O aviso de fingerprint aparece de novo depois de reinstalar a VPS — normal, a máquina
mudou. Remova a entrada antiga com
ssh-keygen -R SEU_IPe conecte novamente.
Passo 3 — Crie o seu usuário não-root
Seção intitulada “Passo 3 — Crie o seu usuário não-root”É ele quem vai operar a VPS daqui em diante:
adduser SEU_USUARIO # troque SEU_USUARIO pelo nome que quiser; você escolhe a senha na horausermod -aG sudo SEU_USUARIO # dá permissão de administrador (sudo)
# --- Errou a senha, desistiu no meio ou quer recomeçar? Escolha UMA das duas: ---passwd SEU_USUARIO # define/redefine só a senha, mantendo o usuáriodeluser --remove-home SEU_USUARIO # apaga o usuário e a pasta dele, para criar tudo de novo👤 Travou no adduser? O que aparece e o que preencher
Ao rodar adduser SEU_USUARIO, o sistema faz uma série de perguntas. Nos exemplos abaixo
usamos “kelvin” como nome de exemplo — no seu caso vai aparecer o nome de usuário que você
escolheu. É assim que aparece:
Adding user `kelvin' ...Adding new group `kelvin' (1000) ...Adding new user `kelvin' (1000) with group `kelvin' ...Creating home directory `/home/kelvin' ...Copying files from `/etc/skel' ...New password:Retype new password:passwd: password updated successfullyChanging the user information for kelvinEnter the new value, or press ENTER for the default Full Name []: Room Number []: Work Phone []: Home Phone []: Other []:Is the information correct? [Y/n]O que preencher, passo a passo:
New password:— crie uma senha forte que você vai lembrar (é a senha do seu usuário, usada no SSH e nosudo). Atenção: nada aparece enquanto você digita — nem*. É normal, a senha está sendo registrada. Digite e pressione Enter.Retype new password:— repita a mesma senha.Full Name,Room Number,Work Phone,Home Phone,Other— dados opcionais. Pode deixar tudo em branco: basta pressionar Enter em cada um.Is the information correct? [Y/n]— digiteY(ou só Enter) para confirmar.
Erros comuns:
-
Sorry, passwords do not matchseguido deTry again? [y/N]— as duas senhas digitadas foram diferentes. Respondaypara digitar de novo. Cuidado com oNmaiúsculo: ele é o padrão, então só pressionar Enter é o mesmo que respondern.E se eu já respondi
n? Aí oadduserdesiste da senha mas continua e cria o usuário — você vai verpasswd: password unchangede, no final,Adding new user .... O usuário existe, mas sem senha, e não consegue entrar por SSH. Não é perda: defina a senha agora, sem recriar nada.Janela do terminal passwd SEU_USUARIOSe preferir começar do zero, apague e rode o
adduserde novo:Janela do terminal deluser --remove-home SEU_USUARIO -
Digitei
n(ou qualquer coisa) emRoom Number/Work Phone— são campos puramente cosméticos, não afetam login nem permissão. Se quiser limpar:chfn SEU_USUARIOe pressione Enter em cada campo. -
BAD PASSWORD: ...— aviso de senha fraca. O sistema aceita, mas prefira uma senha longa (frase com palavras + números, ex.:cavalo-bateria-42-janela). -
“Acho que digitei errado porque não vi nada” — sem problemas: se errou, o
adduserreclama (Sorry, try again.) e pede de novo.
Confira que deu certo antes de seguir:
id SEU_USUARIOTem que aparecer sudo na lista de grupos. Se não aparecer, o segundo comando não pegou.
Agora encerre a sessão de root. Não vamos reconectar ainda — o próximo passo acontece no
seu computador, e o exit já te deixa lá:
exit # sai do root e fecha a conexão SSHVocê volta para o terminal do seu computador. É de lá que o Passo 4 continua.
🤔 E o su - SEU_USUARIO, não serve?
Serve, e é mais rápido — mas tem um efeito colateral que vale conhecer.
Com su - SEU_USUARIO você continua dentro da sessão do root — apenas com outra identidade por
cima. Um exit te devolve ao root em vez de encerrar o acesso, e é fácil esquecer que aquele
terminal ainda tem uma sessão de root aberta embaixo.
Entrando por SSH direto como o seu usuário, a sessão é dele do começo ao fim: exit encerra de
verdade, e tudo que exigir privilégio vai passar por sudo — que pede senha e fica registrado
no log do sistema. É a diferença entre “estou de root com outro chapéu” e “estou como usuário
comum e peço permissão quando preciso”.
Isso vale ainda mais se você vai deixar a sessão aberta por um tempo: melhor que ela seja a do seu usuário, não a do root.
E por que não usamos esse atalho aqui? Além da sessão de root que fica aberta, ele te
mantém dentro da VPS — e o Passo 4 acontece no seu computador. Você teria que sair de qualquer
forma, então o exit resolve as duas coisas de uma vez.
⏱️ Quer controlar quanto tempo a sua sessão SSH sobrevive parada? (opcional — leia se a conexão cai sozinha quando você para de digitar)
Se você já percebeu a sessão fechando depois de alguns minutos parado, o culpado quase sempre é o provedor da VPS, não o servidor: firewalls de rede costumam descartar conexões que ficam um tempo sem tráfego. O seu computador pode resolver isso mandando um sinal de vida a cada minuto. Rode no seu computador, não na VPS:
# no SEU computador (Linux/macOS). No Windows com PuTTY, o campo equivalente é# "Seconds between keepalives" em Connection.printf 'Host *\n ServerAliveInterval 60\n ServerAliveCountMax 3\n' >> ~/.ssh/configDepois disso, reconecte. Isso não enfraquece a segurança — a sessão continua sendo encerrada se a rede realmente cair; o que muda é que ela para de parecer abandonada enquanto você está trabalhando.
Passo 4 — Gere sua chave SSH
Seção intitulada “Passo 4 — Gere sua chave SSH”Faça isso antes de ir para o wizard.
A etapa de Segurança do wizard vai desligar o login por senha no SSH (fase 02 do hardening). A partir daí, a chave é a sua porta de entrada — e o wizard pede a chave pública já na primeira fase, com um rollback automático de 5 minutos correndo. Gerando agora, com o terminal já aberto, você não para no meio do processo para trocar de janela.
Você acabou de sair da VPS, então já está no lugar certo: os comandos abaixo rodam no seu computador. É nele que a chave precisa existir para você se autenticar depois — se ela fosse gerada na VPS, não serviria para entrar nela.
Primeiro, veja se você já tem uma chave. Se você já usa SSH para alguma coisa — GitHub, outro servidor, o trabalho — ela provavelmente já existe, e gerar outra por cima apaga a antiga. Rode:
ls -l ~/.ssh/*.pubNo Windows (PowerShell):
Get-ChildItem ~\.ssh\*.pubOlhe só o nome dos arquivos que apareceram e siga a primeira linha da tabela que bate com o que você viu:
| Se na lista aparece… | Use esta chave | O que fazer agora |
|---|---|---|
id_ed25519.pub (mesmo que apareçam outros arquivos junto) | id_ed25519 | Não gere nada. Vá direto para ⬇️ Instale a chave na VPS (é um link — clique nele) |
id_rsa.pub, mas não id_ed25519.pub | id_rsa | Não gere nada. Vá para ⬇️ Instale a chave na VPS e, lá, use os comandos com id_rsa |
Só arquivos com outros nomes (ex.: github_deploy.pub, algum_servico_deploy.pub) | nenhuma delas | Gere uma chave nova no próximo bloco |
No such file or directory (ou nada) | — | Gere uma chave nova no próximo bloco |
Por que essa regra, e não “escolha a que achar melhor”:
id_ed25519eid_rsasão nomes que osshexperimenta sozinho toda vez que você conecta. Usando uma delas, o login na VPS funciona sem nenhuma configuração extra no seu computador. Aid_rsaé mais antiga, mas o servidor aceita do mesmo jeito.- Chaves com outros nomes foram criadas para um serviço específico (um deploy, uma empresa,
uma ferramenta). Não reaproveite: além de o
sshnão tentá-las sozinho, misturar acessos significa que quem tem aquela chave passa a entrar também na sua VPS. - Gerar uma
id_ed25519nova, nesses dois últimos casos, não apaga nada — ela ainda não existe, então não há o que sobrescrever.
Agora sim, gere o par de chaves (só se a tabela acima mandou gerar). É o mesmo comando no Linux, no macOS, no WSL e no PowerShell do Windows:
ssh-keygen -t ed25519Ele faz três perguntas, nesta ordem:
| O que aparece | O que fazer |
|---|---|
Enter file in which to save the key (...id_ed25519): | Só Enter — aceita o local padrão |
Enter passphrase (empty for no passphrase): | Digite uma senha. Nada aparece na tela, nem asterisco |
Enter same passphrase again: | Repita a mesma |
A passphrase é uma senha extra que protege a chave caso alguém tenha acesso ao seu computador. Ela é recomendada, e para não digitá-la a cada conexão você pode guardá-la na sessão:
eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519Quando o comando terminar, confira que a chave foi criada:
cat ~/.ssh/id_ed25519.pubNo Windows (PowerShell) o comando para exibir é outro:
Get-Content ~\.ssh\id_ed25519.pubVai aparecer uma única linha, longa, mais ou menos assim:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH8k2p... seu-usuario@seu-computadorSe a linha apareceu, a chave está criada.
Instale a chave na VPS — agora, enquanto a senha ainda funciona. O comando sempre diz qual arquivo instalar; use a linha da chave que a tabela escolheu:
ssh-copy-id -i ~/.ssh/id_ed25519.pub SEU_USUARIO@SEU_IPSe a tabela mandou usar a id_rsa, a linha é esta (em vez da de cima):
ssh-copy-id -i ~/.ssh/id_rsa.pub SEU_USUARIO@SEU_IPEle pede a senha do adduser uma última vez e grava a sua chave pública no servidor. No
Windows (PowerShell), onde o ssh-copy-id não existe, o equivalente é:
Get-Content ~\.ssh\id_ed25519.pub | ssh SEU_USUARIO@SEU_IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"Com a id_rsa, troque id_ed25519.pub por id_rsa.pub nessa linha. Daqui em diante, sempre que
um comando citar id_ed25519 (o cat, o ssh-add), quem usa id_rsa faz a mesma troca.
Agora teste, e é o teste que importa:
ssh SEU_USUARIO@SEU_IPSe você entrar sem que ele peça a senha da conta, está funcionando. Ele pode pedir a passphrase da chave — isso é outra coisa, é local, e não tem relação com o servidor.
🔑 E se eu perder, apagar ou corromper a chave privada?
Prevenção (faça isso antes de seguir em frente):
-
Guarde uma cópia da chave privada em lugar seguro, como um gerenciador de senhas. Quem tiver essa cópia acessa a VPS — trate-a como uma senha.
-
Alternativa mais robusta: tenha uma segunda chave, gerada num outro dispositivo (outro computador, ou o seu celular). O campo do wizard aceita uma chave por vez, então instale a segunda depois de concluir o wizard, enquanto a primeira ainda funciona.
Pegue a chave pública do outro dispositivo (o conteúdo do
.pubdele), conecte na VPS pelo computador que já tem acesso e acrescente a linha:Janela do terminal echo "COLE_AQUI_A_SEGUNDA_CHAVE_PUBLICA" >> ~/.ssh/authorized_keysUse
>>e não>— um>sozinho apaga as chaves existentes e te tranca para fora na próxima conexão. Confira o resultado comcat ~/.ssh/authorized_keys: devem aparecer as duas linhas. Assim, perder um dispositivo não te deixa sem acesso.
Se você já perdeu a chave — ou a senha, ou o acesso ao painel — veja Perdi o acesso: e agora?, que cobre cada caso e o caminho de volta.
O teste acima já te deixou conectado na VPS. A partir daqui, todos os passos são feitos lá,
com esse usuário — o que precisar de permissão de administrador vai pedir sudo e a sua senha.
Passo 5 — Instale o git
Seção intitulada “Passo 5 — Instale o git”sudo apt update && sudo apt install -y git📦 O git já estava instalado. Isso é normal?
É normal, sim. “Ubuntu 24.04 LTS” no painel do seu provedor quase nunca é o sistema cru da
Canonical: é um template montado pelo provedor, e git, curl, wget e vim costumam vir
nesse pacote. Encontrar o git já pronto numa máquina recém-criada não indica que alguém entrou
nela.
O comando do Passo 5 continua valendo: se o pacote já estiver lá, o apt responde
git is already the newest version e não faz nada.
Quer confirmar em vez de confiar? São três verificações de leitura, nenhuma altera o sistema:
dpkg -V git # silêncio = arquivos idênticos aos do pacote oficialapt-cache policy git # a origem deve ser archive.ubuntu.com ou security.ubuntu.comlast -a | head # só os seus próprios logins devem aparecerO dpkg -V compara cada arquivo instalado com a assinatura oficial do pacote — nenhuma saída
é o resultado bom. No apt-cache policy, o que importa é a origem: um repositório
desconhecido aí, sim, seria motivo para parar e investigar.
🔑 Primeiro sudo: o aviso gigante e a senha que não aparece
Na primeira vez que você usa sudo com um usuário novo, aparece um aviso clássico:
We trust you have received the usual lecture from the local SystemAdministrator. It usually boils down to these three things:
#1) Respect the privacy of others. #2) Think before you type. #3) With great power comes great responsibility.
[sudo] password for kelvin:O que fazer:
- O aviso é só cerimônia de boas-vindas (uma tradição do Linux) — não exige resposta.
- Em
[sudo] password for kelvin:(no seu terminal vai aparecer o nome do usuário que você criou, não “kelvin”), digite a senha do SEU usuário (a que você criou noadduser), não a senha de root. - Lembre-se: nada aparece na tela enquanto você digita — nem
*. Digite e Enter.
Esse aviso longo só aparece uma vez. Depois disso o sudo pede a senha direto — e, por
alguns minutos, nem isso (ele “lembra” que você se autenticou).
Erros comuns:
-
Sorry, try again.— senha errada. Você tem 3 tentativas antes de o comando falhar. -
kelvin is not in the sudoers file— o usuário não tem permissão de administrador, porque ousermoddo Passo 3 não chegou a rodar para este usuário. Como o própriosudoestá bloqueado, a correção tem que ser feita como root. No seu computador, abra a sessão de root, dê a permissão e confirme:Janela do terminal ssh root@SEU_IPusermod -aG sudo SEU_USUARIOid SEU_USUARIO # tem que listar "sudo"exitE agora o detalhe que engana todo mundo: volte ao terminal do seu usuário, feche a sessão com
exite conecte de novo. O Linux só lê os grupos de um usuário no momento em que a sessão abre — a sua foi aberta antes de o grupo existir, então ela continuaria recusando o comando mesmo com a correção já aplicada. Reconectado, teste comsudo whoami: deve responderroot.
Passo 6 — Clone o repositório
Seção intitulada “Passo 6 — Clone o repositório”Clone em /opt e dê a propriedade da pasta ao seu usuário:
sudo git clone --branch main https://github.com/kelvindk9w/tws-panel.git /opt/tws-panelsudo chown -R $USER:$USER /opt/tws-panelcd /opt/tws-panelPasso 7 — Rode o instalador
Seção intitulada “Passo 7 — Rode o instalador”O instalador instala o Docker se necessário, builda a imagem, sobe os containers
e termina mostrando o endereço do seu painel, já com HTTPS:
https://SEU-IP-COM-HÍFENS.sslip.io (ex.: https://203-0-113-10.sslip.io). Sem túnel e sem
escolher porta.
./scripts/install.sh🩺 Pré-flight: o que aparece na tela e o que fazer em cada cenário
Cenário 1 — VPS limpa (o esperado): o relatório sai todo verde e a instalação segue sozinha, sem pedir nada:
[tws-panel] Pré-flight: inspecionando a máquina (nada será alterado nesta etapa)… ✓ SO: Ubuntu 24.04.2 LTS (suportado) ✓ RAM: 1984 MB ✓ Disco livre em /: 23 GB ✓ Docker: ausente (será instalado por este script) ✓ Nenhum container Docker em execução ✓ Portas do proxy e do e-mail (80/443/25/465/587/143/993/8080) livres[tws-panel] Máquina limpa detectada ✓ — prosseguindo com a instalação.Não precisa fazer nada — só aguardar o build (leva alguns minutos na primeira vez).
Cenário 2 — VPS já em uso: o relatório mostra itens com ⚠ e o instalador para e
espera sua decisão:
⚠ Portas em uso: 80 443 ⚠ Serviço ativo: nginx
================================================================================ ⚠️ ATENÇÃO: esta VPS NÃO parece estar limpa (2 ponto(s) acima).
O TWS Panel foi feito para uma VPS Ubuntu LIMPA. Continuar pode causar conflitos (portas, serviços, recursos) com o que já existe na máquina. Este instalador NUNCA remove ou para nada que já exista — mas os serviços do painel podem falhar ao subir se as portas estiverem ocupadas.
Para prosseguir mesmo assim, digite "continuar" — ou rode com --force (PAAS_FORCE=1) em automações.================================================================================
Digite "continuar" para prosseguir:O que fazer:
- Recomendado: pressione Ctrl+C (ou simplesmente não digite nada e feche) para abortar — nada foi instalado nem alterado. Resolva os conflitos (ex.: desative o nginx se ele não é mais usado, ou contrate uma VPS limpa) e rode o instalador de novo.
- Se você sabe o que está fazendo (ex.: o serviço listado não usa as portas do painel):
digite
continuare pressione Enter. Ao digitar, você confirma que leu o relatório e aceita o risco de conflitos.
Erros comuns:
- Digitou errado (
continua,Continuar) — o instalador aborta comInstalação abortada. Nada foi instalado ou alterado.É só rodar de novo. - Não use
--forceno seu primeiro contato — ele pula exatamente a reflexão que este aviso quer provocar. O--forceexiste para automação, não para pressa.
Logo depois do pré-flight, o instalador faz duas perguntas. Elas decidem como o terminal ao vivo do painel trabalha — é nele que a varredura de segurança e o hardening rodam:
- Com qual usuário o terminal abre. Ele mostra os usuários da VPS que têm permissão de
administrador, mas quem digita o nome é você — mesmo que só exista um. Digite o usuário
que você criou no Passo 3.
roottambém é aceito, mas não recomendamos: uma aba do navegador esquecida aberta daria acesso de root à VPS para quem sentasse na frente dela. - Como rodar o que precisa de root. Responda
1(senha) — é o recomendado: quando algo precisar de administrador, o painel usa osudodentro do terminal e você digita a sua senha ali, como faria por SSH. A outra opção,2(segundo-plano), não pede senha: esses comandos rodam como root por trás, e você confere depois na tela de Auditoria.
Se o usuário não servir (não existe, está sem senha, não tem sudo…), o instalador explica o que
fazer e pergunta de novo. Nada é instalado antes de você responder. A porta do painel ele escolhe
sozinho: ela é só interna, você nunca vai digitá-la.
🔑 Senha ou segundo plano? O que acontece em cada um, sem letras miúdas
Modo senha (recomendado). O terminal abre como o seu usuário. Quando uma varredura ou uma fase
do hardening precisa de root, o painel roda o comando com sudo no próprio terminal, e o sudo
pede a sua senha — a mesma do adduser. Nada roda como administrador sem você ver e autorizar.
- O trade-off: a senha sai do seu navegador, passa pelo painel e chega ao terminal da VPS. Ela não é gravada, registrada nem enviada a lugar nenhum — o projeto é open source e isso pode ser conferido no código. No caminho entre o seu navegador e a VPS ela vai criptografada: o painel é aberto por HTTPS (ou pelo túnel SSH, se você escolher esse acesso).
- Exige que o usuário tenha senha e esteja no grupo
sudo— o que o Passo 3 já fez.
Modo segundo-plano. O terminal também abre como o seu usuário, mas os comandos que precisam de
root rodam como root, por trás, pela mesma ponte que o painel já usa para falar com a VPS. A
saída aparece no terminal só para você acompanhar.
- O trade-off: não pede senha, então você não autoriza comando a comando. A conferência é depois: tudo fica registrado na tela de Auditoria do painel.
- Não exige
sudo— dá até para usar um usuário criado só para o painel. O instalador avisa se o usuário escolhido não tiversudo, porque aí, entrando por SSH com ele, você não consegue fazer nada como administrador.
Nos dois modos, o monitoramento automático agendado — que roda sozinho, sem ninguém para digitar senha — continua executando como root em segundo plano, e cada execução fica registrada na Auditoria.
Condição para os dois modos protegerem de verdade: o usuário do terminal não pode estar no
grupo docker. Quem está nesse grupo vira root sem senha com um único comando, então passaria
por cima tanto do pedido de senha quanto da Auditoria. Se ele estiver, o instalador avisa e oferece
remover — veja Por que o painel não te coloca no grupo docker.
Instalando por automação (sem ninguém para responder)? Passe as escolhas direto:
./scripts/install.sh --terminal-user=SEU_USUARIO --root-mode=senhaSem essas opções, com --force ou sem terminal interativo, o instalador não adivinha: mantém o
comportamento antigo (terminal como root) e avisa. Numa reinstalação, o que você escolheu da
primeira vez é mantido sem perguntar de novo — para trocar, veja
Trocar o usuário do terminal do painel.
🔐 Opcional — acesso só por túnel SSH (o painel fica invisível na internet)
Por padrão o painel abre em https://SEU-IP-COM-HÍFENS.sslip.io. Se você preferir que ele não
tenha endereço nenhum na internet — só quem tem SSH na VPS chega nele —, instale com:
./scripts/install.sh --acesso=tunelNesse modo o instalador pergunta em qual porta da VPS o painel fica e termina mostrando o comando
do túnel SSH e o endereço http://localhost:PORTA/?token=…. O navegador vai mostrar “Não seguro”
por ser http://localhost — e aqui não tem problema: o tráfego viaja criptografado dentro do túnel
SSH. Para trocar de modo depois, rode o instalador de novo com --acesso=https ou --acesso=tunel.
Com o painel em HTTPS, a Fase 02 fecha também o túnel SSH (não é usado); ao trocar para
--acesso=tunel, o instalador libera o túnel de novo sozinho.
Erros comuns ao abrir o túnel:
bind [127.0.0.1]:9000: Address already in use(ao abrir o túnel) — a porta ocupada é a do seu computador, não a da VPS: o número da esquerda nossh -L. Algum programa seu já está usando a 9000 (é comum em quem programa). Troque só esse número e abra o navegador nele:ssh -L 9100:localhost:9000 SEU_USUARIO@SEU_IP, depoishttp://localhost:9100/?token=.... Qualquer número alto e livre serve — 9100, 9300, 12345. Entenda as duas portas do túnel. Na próxima instalação, esse erro nem aparece se você conferir antes qual porta está livre no seu computador e informar esse número ao instalador.- “Não é possível acessar esse site” no navegador, com o túnel aberto — o endereço está com o
número errado. O que vai no navegador é sempre o número da esquerda do seu
ssh -L, que é a porta do seu computador. Se o seu túnel éssh -L 9100:localhost:9001, o endereço éhttp://localhost:9100/?token=...— a9001é a porta da VPS e nunca aparece no navegador. Confira qual número o seu túnel está escutando comss -ltnH 'sport = :9100'(Linux/WSL). channel 2: open failed: connect failed: Connection refused(o túnel abre, mas o navegador diz que não conseguiu conectar) — aí é o outro lado: o número da direita não bate com a porta em que o painel está na VPS. Confira comsudo ./scripts/show-token.sh, que imprime o comando já com a porta certa.
Passo 8 — Abra o painel
Seção intitulada “Passo 8 — Abra o painel”Abra o painel no endereço https://…sslip.io que o instalador mostrou no final (ele já
leva o setup token no link; se precisar, o token também aparece em destaque no terminal) e siga
o wizard. O assistente abre no idioma do seu navegador (veja Idioma da interface logo abaixo).
┌──────────────────────────────────────────────────────────────────────┐│ Assistente — https://SEU-IP.sslip.io/?token=… │├──────────────────────────────────────────────────────────────────────┤│ 1. Boas-vindas e token → valida o setup token e libera o ││ terminal ao vivo do servidor ││ 2. Saúde da máquina → CPU, RAM, disco, rede — os checks ││ rodam AO VIVO no terminal embutido ││ 3. Segurança → scan Lynis → plano → hardening ││ (com rollback automático em 5 min) ││ 4. Conta de administrador → usuário + senha forte do painel │└──────────────────────────────────────────────────────────────────────┘
Idioma da interface. O painel está disponível em português e em inglês. Na primeira visita, ele
percorre a lista de idiomas do navegador e usa o primeiro que tem: português para qualquer variante
de pt (como pt-BR), inglês para en; se nenhum combinar, inglês. Para mudar, use o seletor
Idioma nas telas do assistente e de login, no cabeçalho do painel (ao lado do menu do usuário, sempre à vista depois do login; na disposição lateral, no rodapé da lateral, acima do menu do usuário) ou em
Configurações → Aparência. A escolha fica guardada só nesse navegador (não faz parte da sua
conta); outro navegador ou aparelho começa de novo pelo idioma dele. As mensagens que o próprio
servidor escreve (veja o aviso no topo desta página) continuam em português.
A etapa Segurança é a que exige mais atenção: ela mexe em como você entra na VPS. Antes de aplicar as fases, leia o Wizard de segurança.
O instalador é idempotente: pode ser executado de novo sem quebrar nada (rebuild + restart).
O painel roda 100% em Docker (docker compose up -d), com o estado persistido no volume
paas_data e acesso ao socket do Docker para gerenciar Caddy, Stalwart e seus projetos.
🎫 Banner final do instalador — e como recuperar o token depois
Quando a instalação termina, o terminal toca um “bip” e mostra um banner assim:
████████████████████████████████████████████████████████████████████████████████ ████ ✅ TWS PANEL INSTALADO E RODANDO COM SUCESSO! ████ ████████████████████████████████████████████████████████████████████████████████
👉 PRÓXIMO PASSO: abra o painel no navegador
Abra no navegador (de qualquer computador — não precisa de túnel nem de porta):
https://203-0-113-10.sslip.io/?token=<seu-token-de-48-caracteres>
A conexão é criptografada (HTTPS, certificado Let's Encrypt): a senha de administrador que você vai criar e a senha do sudo, se o terminal pedir, trafegam protegidas. O sslip.io só traduz o nome para o IP desta VPS — o tráfego vai direto do seu navegador para cá.
┌──────────────────────────────────────────────────────────────────────────┐│ ⚑ SETUP TOKEN ⚑ ││ ││ <seu-token-de-48-caracteres> ││ ││ ⚠ Ele aparece SÓ AGORA em destaque. Guarde-o até concluir o wizard. ││ ⚠ Após criar a conta admin no fim do wizard, ele é invalidado. │└──────────────────────────────────────────────────────────────────────────┘O que fazer: copie o link completo (https://…sslip.io/?token=...) e cole no navegador.
Ele já leva o token embutido — não precisa digitar nada. Instalou com --acesso=tunel? O banner
mostra, no lugar dele, o comando do túnel e o endereço http://localhost:… (veja
Acesso por túnel SSH).
Fechou o terminal e perdeu o banner? Sem pânico. Na VPS, rode qualquer um dos dois:
sudo ./scripts/show-token.sh # reexibe o link completo + tokensudo docker exec tws-panel cat /data/setup-token # mostra só o tokenErros comuns:
- O instalador disse que o endereço
https://…sslip.ionão respondeu em 3 minutos — o certificado não saiu. A causa mais comum são as portas 80 e 443 bloqueadas num firewall do provedor (no painel da hospedagem): libere as duas e reinicie o painel comsudo docker compose restart. Para ver o que o proxy diz:sudo docker logs paas-caddy --tail 50. Enquanto isso, o acesso por túnel funciona (o banner mostra o comando). - Erros ao abrir o túnel (só no acesso por túnel) — estão explicados em Acesso por túnel SSH.
permission denied while trying to connect to the Docker daemon socket— faltou osudona frente do comando. É de propósito: o painel não coloca ninguém no grupo docker (veja o porquê).setup token não encontrado...— ou oshow-token.shfoi rodado numa máquina sem o painel (rode-o na VPS certa, de dentro de/opt/tws-panel), ou o assistente já foi concluído e o token foi apagado de propósito: para reabri-lo com um token novo,sudo ./scripts/reset-setup.sh.- O token não funciona mais no navegador — depois que você cria a conta admin (última etapa do wizard), o token é invalidado para sempre. A partir daí o acesso é pela tela de login, com seu usuário e senha do painel.
Depois do wizard
Seção intitulada “Depois do wizard”No primeiro acesso, o Dashboard mostra o roteiro Deixe o painel pronto, com o que ainda falta configurar (proteções, verificação em duas etapas, domínio do painel, e-mail, notificações e backups). A Parte 2 percorre cada um deles, em ordem.
Para publicar um projeto: cadastre o projeto, aponte o DNS, e o painel cuida do build, do proxy e do SSL. Guia de produção em production.md. Comandos do dia a dia, pasta dos projetos e troca de porta ou de usuário do terminal estão em Operação.