Pular para conteúdo

Ambientes e deploy

Os ambientes

Ambiente Aplicação Documentação Evolution
Desenvolvimento kpmentoring.emshome.com.br kpdocs.emshome.com.br servidor de produção, compartilhado
Produção app.keilladepaula.com.br kpdocs.keilladepaula.com.br evo.keilladepaula.com.br

O apex keilladepaula.com.br é um WordPress de terceiro e não faz parte deste sistema.

Dev aponta para o Evolution de produção

Os dois ambientes usam o mesmo servidor Evolution, e o webhook de uma instância tem um destino só. Pedir QR code no dev repointa a instância e deixa a produção surda. Ver Evolution API.

Portas no desenvolvimento

Frontend em 3010 e backend em 8010. A porta 3000 é outro aplicativo e responde 404 nas rotas internas.

Fluxo de branches

flowchart LR
  F[feature] --> D[developer]
  D --> M[main]
  M -->|timer na VPS| P[produção]

A main deploya sozinha, por timer na VPS. Merge na main é publicar.

Como o deploy roda

Não há Docker. A aplicação roda em PHP-FPM com Apache, e o frontend e a fila em PM2.

Passo Detalhe
composer install Sem dev, com autoloader otimizado
Build do frontend Antes de derrubar qualquer processo, para que uma falha de build não cause indisponibilidade
migrate --force Só migrations; nunca seed
Recarga do PHP-FPM Obrigatória, porque opcache.validate_timestamps está desligado
Restart no PM2 Frontend e fila

Permissão nova precisa de migration

O deploy não roda seed. Uma permissão declarada apenas no ProfileSeeder nunca chega à produção. Ver AD-010.

Duas armadilhas de configuração

Ao mexer no .env de produção, rode config:cache de novo, senão a mudança não vale. E NEXT_PUBLIC_API_URL é embutido no bundle: mudá-lo exige rebuild, não restart.

Permissão da mídia

O worker da fila grava o anexo do WhatsApp e o PHP-FPM serve. Se os dois não puderem ler o mesmo arquivo, a rota devolve 404, o áudio não toca e o avatar cai nas iniciais, sem erro visível.

Em 12/09/2026 isso era um defeito de produção. O worker herdava o root do daemon do PM2 e os diretórios nasciam root:root 0700, que outro usuário não atravessa.

A correção tem três partes, e nenhuma basta sozinha:

Parte Por que é necessária
uid e gid www-data no bloco da fila no PM2 Sem isso o worker é root
chown -R www-data:www-data storage bootstrap/cache Os arquivos já gravados seguiriam ilegíveis
.env em 0640 root:www-data Sem ler o .env, o worker quebra

pm2 restart não reaplica uid

E o deploy usa restart. Instalar essa mudança numa VPS que já roda exige pm2 delete, pm2 start e pm2 save. A consequência boa é que o deploy também não a desfaz.

O disco local declara permissions para que o diretório nasça 0750 em vez do 0700 padrão do Flysystem. Sem isso o defeito voltaria no próximo diretório criado: cada instância de WhatsApp tem o seu, e um deploy em máquina nova cria a árvore toda.

Banco de testes

A suíte usa um banco próprio. Rodá-la sem isolar o banco, enquanto outra sessão roda, produz erros de "relation does not exist" que não têm nada a ver com o código.

DB_DATABASE=kpmentoring_test_<feature> php artisan test

Publicar esta documentação

cd documentacao
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
mkdocs serve          # http://127.0.0.1:8000
mkdocs build          # gera ./site

Como a documentação é servida

Site estático: o Apache serve a pasta documentacao/site, que é a saída do mkdocs build e não é versionada. Sem build, o domínio responde com erro de diretório vazio.

Ambiente Domínio Estado
Desenvolvimento kpdocs.emshome.com.br No ar, com certificado válido até 11/12/2026
Produção kpdocs.keilladepaula.com.br DNS criado; vhost ainda não instalado

O modelo do vhost está em deploy/apache/kpdocs.conf.example. Ele tem só o bloco :80, de propósito: o desafio ACME precisa de HTTP respondendo antes de existir certificado.

# 1. Build, para que o DocumentRoot exista
cd /var/www/kpmentoring/documentacao
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
.venv/bin/mkdocs build --strict

# 2. Vhost só em :80, e confirmar 200 pelo domínio real
a2ensite kpdocs.conf && systemctl reload apache2
curl -s -o /dev/null -w '%{http_code}\n' http://kpdocs.keilladepaula.com.br/

# 3. Certificado; o certbot escreve o :443 e o redirecionamento sozinho
certbot --apache -d kpdocs.keilladepaula.com.br --redirect

Cloudflare em proxy quebra o desafio HTTP

O desafio ACME precisa alcançar este servidor. Se o registro estiver em modo proxy, desligue o proxy durante a emissão ou use desafio por DNS.

O MkDocs não precisa de rewrite

Ele gera pagina/index.html, então DirectoryIndex resolve as URLs. O ErrorDocument 404 /404.html é o que entrega a página de erro do próprio tema.

Os dois domínios

O site_url muda por ambiente, e sem ele o sitemap.xml sai com URLs relativas. São dois arquivos de configuração: o principal aponta para produção, e o de dev herda dele e troca só o que precisa.

mkdocs build                      # produção, kpdocs.keilladepaula.com.br
mkdocs build -f mkdocs.dev.yml    # dev, kpdocs.emshome.com.br

O mkdocs.dev.yml usa a chave INHERIT do MkDocs, então ele tem três linhas e nunca sai de sincronia com a navegação.