Solução de Problemas
Esta página é uma referência organizada por sintoma. Encontre a seção que descreve o que você está vendo e siga o formato Problema → Causa provável → Como resolver. Muitas correções acontecem nas configurações do próprio site (limite de memória, document root, auto-deploy) ou na aba de bancos de dados do servidor — as duas telas que mais aparecem aqui.

Deploys que falham
Deploy travado no estado "Locked"
Causa provável: um deploy anterior travou sem liberar o bloqueio (lock). Isso acontece se o servidor perdeu conectividade no meio do deploy ou uma operação de container expirou.
Como resolver:
- Veja o status do site no painel e leia o log do último deploy em busca de erros.
- Use a ação Cancelar Deploy no deploy em andamento, se ele ainda aparecer como Running.
- Dispare um novo deploy. O PrimeForge detecta locks obsoletos automaticamente após 15 minutos, e todo reinício do container do painel também limpa deploys interrompidos — então, na maioria dos casos, um reinício do painel já destrava sozinho.
Health check falha depois do deploy
Sintoma: o deploy passa por todos os estágios, mas falha no health check com uma resposta diferente de 2xx/3xx.
Causa provável e correção:
| Causa | Correção |
|---|---|
| Migração falhou | Veja os erros de SQL nos logs do deploy. Corrija a migração e faça o deploy de novo. |
| Variável de ambiente faltando | Confira o Editor de Ambiente. O estágio de enriquecimento preenche a partir do .env.example, mas não inventa segredos. |
| Erro de dependência PHP | Veja a saída do composer install nos logs. |
| Build do Node falhou | Veja a saída do npm run build nos logs. |
| Esgotou a memória | Aumente o limite de memória do site (veja a seção Memória e OOM). |
| Erro da aplicação | Veja o laravel.log na aba de Logs do site. |
PHP Clássico com 404 na raiz / |
O Document Root precisa apontar para onde está o seu index.php. Se o repositório tem index.php na raiz, defina o Document Root como . (e não public). Ajuste em Configurações → Configuração do Site e faça um novo deploy. |
Deploy expira (timeout)
Causa provável: o estágio de build ou de script demora mais que o tempo limite de 15 minutos.
Como resolver: otimize o composer install removendo pacotes não usados; exclua diretórios grandes do repositório; quebre migrações pesadas em lotes menores; e verifique os recursos do servidor — pouca RAM deixa o build lento.
Deploy falha com "exit code 137" / "Killed" / build ficou sem memória
Sintoma: o log do deploy mostra algo como Command failed (exit code 137), Killed, OOMKilled, JavaScript heap out of memory ou Fatal error: Allowed memory size.
Causa provável: o container do site ficou sem memória durante o build. É comum em sites Laravel com package.json grande (Vite + Tailwind + Alpine + Livewire) ou apps Node/Next.js pesados em TypeScript — npm ci + npm run build pode chegar a 1,5–2 GB.
Como resolver: o PrimeForge detecta esse tipo de falha e mostra, no deploy que falhou, um botão "Aumentar memória para {N} e tentar de novo". Clique nele: o painel dobra o limite de memória do container do site (até o teto de 4 GB) e refaz o deploy sozinho — sem SSH. Se preferir ajustar à mão, vá em Configurações → Configuração do Site → Limite de Memória e escolha um valor maior (1 GB ou 2 GB costuma ser o ponto ideal para Laravel), depois clique em Deploy.
Novos sites Laravel, Node.js e Next.js já são criados com
memory_limit=1Gpara evitar essa cilada no primeiro deploy. Sites HTML Estático e PHP Clássico ficam em512M, pois não têm etapa de build.
"Disk critical" bloqueando deploys
Causa provável: o uso de disco do servidor está em 90% ou mais. O PrimeForge bloqueia todos os deploys para não deixar o servidor ficar completamente sem espaço.
Como resolver: veja o uso de disco na aba de monitoramento do servidor; limpe imagens e volumes Docker não usados; apague backups antigos guardados localmente; ou considere aumentar o disco. Um alerta disk.warning dispara em 75% e disk.critical em 90% — configure a entrega por webhook numa Regra de Alerta para saber disso antes que os deploys quebrem.
Push no GitHub não dispara deploy (auto-deploy)
Causa provável: algo interrompe o caminho do git push até o deploy.
| Problema | Diagnóstico | Correção |
|---|---|---|
| Auto-deploy desligado | Em Site → Configurações → Serviços, o Auto Deploy aparece como Desativado | Ligue-o naquela linha |
| Branch errada | O branch do push não bate com o branch do site | Ajuste o branch nas Configurações, ou envie para o branch configurado |
| Webhook nunca registrado | Em Settings → Webhooks do repositório GitHub não aparece a URL do PrimeForge | Desligue e religue o Auto-Deploy nas Configurações; o log de auditoria mostra o erro de origem |
| Segredo do webhook inválido | Entrega rejeitada com 403 | O segredo mudou desde o registro do hook. Desligue e religue o Auto-Deploy para re-registrar com a URL nova |
"Não foi possível registrar o webhook" ao ativar o Auto-Deploy
Causa provável: o token do GitHub não tem permissão para criar hooks no repositório. Os motivos comuns são um PAT fine-grained sem o repositório-alvo selecionado, um PAT clássico sem o escopo admin:repo_hook, ou o repositório renomeado/excluído desde o registro da credencial.
Como resolver: use um Personal Access Token clássico com os escopos repo e admin:repo_hook, ou atualize o PAT fine-grained para incluir o repositório-alvo. Depois desligue e religue o Auto-Deploy.
Bancos de dados

Erros de conexão recusada
Sintoma: SQLSTATE[08006] Connection refused ou SQLSTATE[HY000] [2002] Connection refused nos logs da aplicação.
Diagnóstico: confira se o serviço de banco está rodando na aba de Serviços/Overview do servidor. Se estiver Parado ou Falho, o PrimeForge tenta a recuperação automática. Veja também a saúde dos serviços no monitoramento.
Causas comuns e correções:
| Causa | Correção |
|---|---|
| Serviço PostgreSQL/MySQL caiu | Aguarde a recuperação automática (3 tentativas). Se continuar fora, reinicie o serviço na aba de Serviços do servidor. |
DB_HOST errado no .env |
Para sites no mesmo servidor, DB_HOST deve ser host.docker.internal. Para cross-server, deve ser o IP da malha WireGuard. |
| Senha divergente | Se um site foi apagado e recriado, o volume do banco pode ter a senha antiga. Apague o volume e faça o deploy de novo. |
| UFW bloqueando o Docker | Garanta que as regras de firewall liberam o acesso da sub-rede Docker às portas do banco. |
Consultas lentas
Sintoma: páginas levam mais de 3 segundos; o monitoramento mostra CPU baixa mas tempo de resposta alto.
Diagnóstico: conte as consultas por página — mais de 10 consultas sugere problema de N+1. Ative Model::preventLazyLoading() no boot() do seu AppServiceProvider para detectar relações carregadas de forma preguiçosa. Verifique índices ausentes em colunas usadas em WHERE, ORDER BY e JOIN.
Correções (em ordem de esforço): adicionar índices ausentes; usar eager loading (->with()) nas consultas Eloquent e nas tabelas do Filament; habilitar conexões persistentes no PHP-FPM; e, para bancos remotos, reduzir o número de consultas — cada consulta soma o ida-e-volta (RTT) da malha WireGuard.
TLS e certificados
Certificado não é emitido
Sintoma: o navegador mostra "Sua conexão não é particular" ou um aviso de certificado.
Diagnóstico: confirme que o DNS aponta para o IP do servidor; garanta que a porta 80 está aberta (o desafio HTTP do Let's Encrypt precisa dela); e veja os logs do container Traefik em busca de erros de ACME.
Causas comuns:
| Causa | Correção |
|---|---|
| DNS não aponta para o servidor | Atualize o registro A do DNS para o IP público do servidor e aguarde a propagação. |
| Porta 80 bloqueada | Confira as regras do UFW. O PrimeForge abre a porta 80 no provisionamento. |
| Limite de emissão do Let's Encrypt | Após 5 certificados em 168 horas para os mesmos domínios, o LE bloqueia novos pedidos. Aguarde e tente de novo. |
| Domínio curinga sem desafio DNS | Desafios HTTP não emitem curingas. Veja abaixo. |
Falha na renovação do certificado
Causa provável: o Traefik renova os certificados sozinho; quando falha, geralmente é porque o desafio HTTP não consegue alcançar a porta 80.
Como resolver: confirme que o Traefik está rodando e que a porta 80 é acessível pela internet. Veja os logs do Traefik para os erros de renovação.
Certificado curinga (wildcard) não é emitido, mesmo com o token válido
Sintoma: sites em um domínio curinga (*.exemplo.com) servem o certificado autoassinado padrão do Traefik; pedidos manuais batem no limite do Let's Encrypt. O token do provedor passa no teste de provisionamento.
Causa provável (DigitalOcean): os tokens do DigitalOcean têm escopos separados para Droplets e para Domains/DNS. Um token que cria droplets pode não ter permissão para criar os registros TXT que o desafio DNS-01 exige para curingas.
Como resolver:
- Abra Credenciais → Provedores de Servidor → (seu provedor DO) → Editar.
- Clique em Testar Token (Domains).
- Se o resultado for MISSING, regenere o token em cloud.digitalocean.com/account/api/tokens com Domains: Read + Write e atualize o provedor.
- Espere 1 hora antes de tentar emitir de novo, para não cair no bloqueio por excesso de tentativas do Let's Encrypt.
WebSockets e Reverb
Eventos não chegam em tempo real
Sintoma: os dados estão corretos ao recarregar a página, mas não atualizam ao vivo. Sem erros no console do navegador.
Diagnóstico: abra o console e verifique Echo.connector.pusher.connection.state — connected (a conexão funciona; o problema está no broadcast), unavailable (o Reverb está inalcançável) ou disconnected (a conexão caiu). Confirme também que BROADCAST_CONNECTION=reverb está no .env e que REVERB_APP_KEY/REVERB_APP_SECRET batem entre o site e o servidor Reverb.
Como resolver: faça um novo deploy do site (isso re-registra o app do Reverb automaticamente); confirme que REVERB_HOST aponta para o domínio correto; e, para sites em servidores remotos, verifique se REVERB_INTERNAL_HOST usa o nome DNS Docker correto.
Erro Pusher 4001 — "Application does not exist"
Causa provável: a app key do Reverb do site não está registrada no servidor Reverb.
Como resolver: faça um novo deploy do site — o PrimeForge registra as apps do Reverb durante o deploy. Se persistir, confira se o Reverb está rodando na aba de Serviços do servidor.
Erro Pusher 4009 — "Origin not allowed"
Causa provável: o domínio do navegador não bate com a origem permitida na configuração da app do Reverb.
Como resolver: confirme que o domínio do site no painel é o mesmo de onde o navegador está conectando. Atualize o domínio se ele tiver mudado.
Memória e OOM
Erros aleatórios 502 Bad Gateway
Sintoma: o site funciona na maior parte do tempo, mas às vezes retorna 502. Reinícios de container aparecem no monitoramento.
Diagnóstico: veja o uso de memória do servidor na aba de Monitoramento — uso sustentado acima de 85% é zona de perigo. Verifique o uso de memória do container (pode estar batendo no limite) e procure "Allowed memory size exhausted" no laravel.log.
Correções (em ordem de eficácia): aumentar a RAM do servidor (a mais confiável); reduzir max_children do PHP-FPM; otimizar o código (chunk em consultas grandes, processar arquivos em streams); adicionar swap (rede de segurança, não solução definitiva); e reiniciar os workers de fila periodicamente (--max-jobs=1000 ou --max-time=3600) para conter vazamentos de memória.
OOM kills (containers reiniciando em tempo de execução)
Sintoma: containers Docker reiniciam sozinhos em runtime (não durante o deploy). O dmesg do servidor mostra "Out of memory: Killed process".
Causa provável: o servidor está ficando sem RAM e o Linux mata containers pelo OOM killer.
Como resolver: reduza o número de sites no servidor; aumente a RAM; ou mova serviços (banco, Redis) para um servidor separado, liberando RAM para os containers de aplicação.
Se o OOM acontecer durante um deploy (e não em runtime), veja a entrada específica em Deploys que falham → "exit code 137" — nesse caso o PrimeForge resolve com um clique a partir do banner do deploy que falhou.
Servidores offline ou inalcançáveis
O que acontece quando o Agent some
Um Agent caído é um problema do plano de controle, não uma queda do site. O Agent é um processo separado dos seus containers de aplicação: quando ele morre, o Docker mantém os containers rodando, o Traefik continua roteando e o visitante não percebe nada. O painel apenas perde os "olhos e mãos" naquele servidor até a conexão voltar. A detecção é em três níveis, pelo tempo desde o último heartbeat:
| Nível | Limite | Status | Cor | O que muda |
|---|---|---|---|---|
| 1 — Queda de conexão | 0s | Ready (inalterado) | verde | Silencioso; o Agent pode reconectar em segundos. |
| 2 — Inalcançável | 90s | Unreachable | âmbar | Dispara um webhook de aviso. Registrado no log. |
| 3 — Offline | 600s (10 min) | Offline | vermelho | Dispara um webhook crítico. O painel marca sites como Failed — mas só no próprio banco dele. |
Seus sites continuam de pé o tempo todo. O painel nunca envia comando de parar quando o Agent some; o selo Failed no Nível 3 é o painel admitindo que não consegue mais confirmar a saúde, e não sinal de que algo parou. Ao reconectar, a reconciliação inspeciona o estado real dos containers e corrige a visão do painel. Além disso, o Agent se cura sozinho — reconecta com backoff exponencial (até 5 minutos) e recarrega a configuração se o token tiver mudado.
É o Agent, ou o VPS inteiro?
A recuperação depende de qual dos dois quebrou, então confirme primeiro:
| Verificação | Agent caiu (VPS vivo) | VPS inteiro caiu |
|---|---|---|
| Overview do painel | selo Unreachable/Offline; "Agent Connected: No" | igual |
| Aba Firewall | mostra "Server agent is offline" | igual |
ssh para o servidor |
funciona | expira / conexão recusada |
| Painel do provedor de nuvem | droplet ligado | droplet desligado/excluído |
Se o SSH funciona, é quase certo que seja o Agent — siga abaixo. Se o próprio SSH expira, o VPS está fora (ou a rede/firewall quebrou) — comece pelo painel do provedor.
Recuperar pelo painel
As ações abaixo ficam no topo da página Overview do servidor e exigem papel Admin ou superior. Estão em ordem do menos ao mais invasivo — comece de cima e só escale se não resolver.
- Force Reconnect Agent — o menos invasivo. O painel faz SSH e reinicia o Agent, pulando o backoff; o servidor deve voltar a Ready em ~10 segundos. Limitado a uma tentativa por minuto por servidor. É o primeiro movimento para um Agent travado num VPS acessível.
- Update Agent — aparece quando o Agent está desatualizado. Atualiza o binário (pela conexão WebSocket, quando o Agent está conectado, ou por SSH quando não está), verificando SHA-256 e versão antes de trocar e restaurando o binário anterior se o novo não reconectar. Use quando a queda é uma versão sabidamente ruim.
- Roll Back Agent — restaura o binário anterior por SSH. Use quando a própria atualização causou a queda.
- Reinstall Agent — o mais invasivo; último recurso. Reenvia o binário, emite um token novo, regenera a configuração e a unit do systemd e aguarda até 90 segundos por um handshake. Precisa de credenciais SSH válidas.
Se o Force Reconnect reportar "Server is unreachable over SSH", o VPS em si está fora — verifique o provedor. Se reportar "Could not SSH into the server", a chave SSH de provisionamento está errada ou foi removida — reprovisione ou atualize as credenciais.
Servidor preso em "Unreachable" após reinício do painel
Causa provável: logo depois de uma indisponibilidade longa do painel, o Agent pode estar esperando o fim de uma janela de backoff (que chega a 5 minutos) antes da próxima tentativa, mesmo com o painel já de volta.
Como resolver: abra a Overview do servidor e clique em Force Reconnect Agent para pular o backoff. O servidor deve voltar a Ready em ~10 segundos.
Excluí um droplet fora do PrimeForge e o site ficou "Failed"
Causa provável: você apagou o droplet direto no provedor (painel do DigitalOcean, doctl, etc.) em vez de usar o botão Excluir do PrimeForge. A linha do Server ficou, o painel acabou marcando o servidor Offline, e os sites apontados para ele caíram para Failed.
Como resolver (automático): um reconciliador roda a cada 15 minutos. Depois que um servidor fica Offline por 10+ minutos, o PrimeForge pergunta ao provedor se o droplet ainda existe; se a resposta for um 404 definitivo, ele remove a linha órfã do servidor, limpa os registros de site e marca os sites afetados como Failed no log de auditoria (server.deleted_externally). O reconciliador nunca age em erros transitórios de API — se o provedor devolve 5xx/401, o servidor é pulado até a próxima passagem.
CloudPrime: a API do CloudPrime não expõe endpoint de exclusão, então esse reconciliador não se aplica. Ao excluir um servidor CloudPrime no PrimeForge, a linha some do painel, mas o VPS continua rodando no CloudPrime — finalize o desligamento no painel do provedor para a cobrança parar.
Página de Firewall mostra "agent offline"
A aba Firewall administra o UFW pelo Agent do servidor. Se o Agent está desconectado (servidor Unreachable/Offline), as regras não podem ser lidas nem alteradas até ele reconectar — a página mostra um aviso em vez de dados desatualizados. Verifique o estado do Agent em Servidor → Overview. Como o canal do Agent não depende de portas de entrada (o Agent conecta para fora), um erro de firewall não corta o controle do PrimeForge sobre o servidor.
Próximos passos
- Guia Fix-Forward — o que fazer quando o banco está à frente do código.
- Boas Práticas de Segurança — como manter a organização segura.
- Modo de Pânico — kill-switch de emergência para conter um site.