# Evolution API - Agência Climb Digital - Fase 1 Deploy

**Data:** 2026-08-10
**Executor:** Paulo (dev)
**Objetivo:** Eliminar dependência da Dinastia auto-hospedando Evolution API self-hosted na VPS da agência.
**Status:** Fase 1 concluída - infra base rodando, aguardando sinal pra Fase 2.

---

## URLs e endpoints

| Item | Valor |
|------|-------|
| Base URL | https://evo.agentesclimb.us |
| Manager UI | https://evo.agentesclimb.us/manager/ |
| Health check | https://evo.agentesclimb.us/ |
| Documentação oficial | https://doc.evolution-api.com/v2/pt/get-started/introduction |
| Versão instalada | evoapicloud/evolution-api:v2.2.3 |

## Credenciais

**Arquivo:** `/opt/mia/config/evolution_api.env` (permissão 600, dono `mia`)

Contém:
- `AUTHENTICATION_API_KEY` - chave master da API Evolution (usar no header `apikey: <valor>`)
- `POSTGRES_PASSWORD` - senha do postgres interno
- `POSTGRES_USER` / `POSTGRES_DB` - `evolution` / `evolution`
- `EVOLUTION_URL` - `https://evo.agentesclimb.us`

Nunca commitar. Nunca vazar em log. Já copiada como `.env` do docker-compose.

## Arquitetura

3 containers isolados via `docker compose` em `/opt/mia/services/evolution_climb/`:

```
evolution-climb-api       (evoapicloud/evolution-api:v2.2.3)
├── evolution-climb-postgres  (postgres:16-alpine, volume evolution_climb_postgres_data)
└── evolution-climb-redis     (redis:7-alpine, volume evolution_climb_redis_data)

Volume evolution_climb_instances -> /evolution/instances (sessões WhatsApp / QR / creds Baileys)
Network evolution_climb_internal (bridge isolada, só entre os 3 containers)

Publicação: 172.18.0.1:8090 -> container:8080
  (docker_gwbridge gateway, alcançável só do host e das overlays swarm - não vaza pra internet)
```

## Fluxo de rede

```
Internet -> Cloudflare (DNS proxied=false) -> IP 72.61.51.166 (VPS)
        -> Traefik (containers swarm easypanel-traefik, portas 80/443)
            -> Rota Host(evo.agentesclimb.us) -> service evolution-climb
                -> http://172.18.0.1:8090
                    -> container evolution-climb-api:8080
```

Rota Traefik configurada em `/etc/easypanel/traefik/config/custom.yaml` (file provider, reload automático):

```yaml
routers:
  evolution-climb-http:
    entryPoints: [http]
    middlewares: [redirect-to-https]
    rule: Host(`evo.agentesclimb.us`)
    service: evolution-climb
  evolution-climb-https:
    entryPoints: [https]
    rule: Host(`evo.agentesclimb.us`)
    service: evolution-climb
    tls:
      certResolver: letsencrypt

services:
  evolution-climb:
    loadBalancer:
      servers:
      - url: http://172.18.0.1:8090
```

Backup do custom.yaml antes de editar: `/etc/easypanel/traefik/config/custom.yaml.bak.<timestamp>`

## DNS

- Domínio: `evo.agentesclimb.us` -> `72.61.51.166` (A record, TTL 120s, proxied=false)
- Zone Cloudflare: `agentesclimb.us` (ID `eac1c8df0852c11234937e011443bbcc`)
- Registro criado via API Cloudflare em 2026-08-10
- **proxied=false é obrigatório** pra Let's Encrypt HTTP-01 funcionar no Traefik. NÃO ativar proxy laranja.

## SSL

- Emitido pelo Let's Encrypt automaticamente via Traefik (certResolver `letsencrypt`)
- Válido de 2026-08-10 até 2026-11-08 (renova sozinho ~30d antes)
- Storage: `/etc/easypanel/traefik/acme.json`

## Config Evolution habilitada

- Banco: Postgres, `DATABASE_SAVE_*` tudo `true` (mensagens, contatos, chats, labels, histórico)
- Cache: Redis `db=6`, prefixo `evolution_climb`, `CACHE_LOCAL_ENABLED=false`
- Webhook GLOBAL desabilitado (será configurado POR INSTÂNCIA nas Fases 3+)
- Log level: `INFO`, Baileys em `error` (menos verbose)
- Language: pt-BR
- QR code limit: 30 tentativas

## Restart / persistência

- Todos os containers com `restart: unless-stopped`
- Docker.service já é `enabled` no systemd -> após reboot da VPS, docker-compose sobe automático
- Volumes nomeados sobrevivem a `docker compose down`. Só perdem em `docker compose down -v` (NÃO USAR sem backup)

## Como operar (dia a dia)

### Ver status
```bash
sudo docker ps --filter name=evolution-climb
```

### Ver logs
```bash
sudo docker logs -f evolution-climb-api --tail 100
sudo docker logs -f evolution-climb-postgres --tail 50
sudo docker logs -f evolution-climb-redis --tail 50
```

### Restart limpo
```bash
cd /opt/mia/services/evolution_climb && sudo docker compose restart evolution
```

### Update de versão
```bash
cd /opt/mia/services/evolution_climb
# editar docker-compose.yml, mudar tag v2.2.3 pra nova versão
sudo docker compose pull
sudo docker compose up -d
sudo docker logs -f evolution-climb-api --tail 100  # monitorar migrations Prisma
```

### Health check
```bash
curl -s https://evo.agentesclimb.us/
# Esperado: {"status":200,"message":"Welcome to the Evolution API, it is working!",...}
```

### Testar autenticação
```bash
EVO_KEY=$(sudo grep AUTHENTICATION_API_KEY /opt/mia/config/evolution_api.env | cut -d= -f2)
curl -s -H "apikey: $EVO_KEY" https://evo.agentesclimb.us/instance/fetchInstances
# Esperado: [] (vazio, nenhuma instância criada ainda)
```

### Login no Manager UI
1. Acessar https://evo.agentesclimb.us/manager/
2. Colar a `AUTHENTICATION_API_KEY` do arquivo env no campo "Global API Key"
3. Criar/gerenciar instâncias visualmente

## Backup mínimo (recomendado antes da Fase 5)

```bash
# Dump do postgres
sudo docker exec evolution-climb-postgres pg_dump -U evolution evolution | gzip > /opt/mia/backups/evolution_$(date +%Y%m%d).sql.gz

# Snapshot dos instances (creds Baileys / QR)
sudo tar -czf /opt/mia/backups/evolution_instances_$(date +%Y%m%d).tar.gz \
    -C /var/lib/docker/volumes/evolution_climb_instances/_data .
```

## Decisões técnicas

1. **Docker-compose fora do EasyPanel** - controle direto via arquivos versionáveis, sem depender da UI. EasyPanel continua gerenciando os outros projetos.
2. **Bind em 172.18.0.1:8090 (docker_gwbridge)** - Traefik roda em swarm overlay, não consegue conectar em `127.0.0.1` do host. Bindar no gateway do docker_gwbridge (que Traefik já usa) resolveu. Alternativas descartadas: (a) attach na overlay swarm - docker-compose bridge não anexa em overlay swarm por default; (b) `network_mode: host` - impede isolamento.
3. **Postgres + Redis próprios** - não reaproveitei os do dinastia (EasyPanel) pra não misturar estado de projetos diferentes. Isolamento facilita rollback.
4. **Webhook global DESABILITADO** - webhooks serão POR INSTÂNCIA (via API do Evolution) nas fases seguintes, apontando pro consumidor certo (torq-sdr, prospeccao, etc).

## Coexistência com os outros Evolutions

Já existem na VPS (não tocados):
- `dinastia_evolution.1.f77c...` - Evolution do projeto EasyPanel "dinastia" (SERVER_URL `dinastia-evolution.sqjked.easypanel.host`)
- `scheduler_evolution_api` - Evolution na porta 8081 (agendador)

Este novo Evolution é INDEPENDENTE. Domínio próprio, portas próprias, banco próprio. Zero risco de conflito.

## Pendências (Fases seguintes)

- **Fase 2:** monitoramento (Uptime Kuma?), auto-recovery além do restart:unless-stopped, alertas Telegram no bot Mia se container cair >2min
- **Fase 3:** criar instância piloto TORQ Bruno, configurar webhook apontando pro endpoint atual do torq-sdr (adaptar payload Dinastia -> Evolution)
- **Fase 4:** validação lado a lado (Dinastia + Evolution rodando em paralelo pro Bruno), comparar entrega
- **Fase 5:** migração dos SDRs PX3 (Monique, Mari, Nayane)
- **Fase 6:** desligar Dinastia, cancelar pagamento

## Checklist Fase 1 (fechada)

- [x] Deploy docker-compose com Postgres + Redis + Evolution v2
- [x] Domínio evo.agentesclimb.us criado no Cloudflare
- [x] SSL Let's Encrypt válido
- [x] AUTHENTICATION_API_KEY forte gerada e salva com perm 600
- [x] Webhook global desabilitado
- [x] Manager UI acessível
- [x] Health check retornando 200
- [x] restart: unless-stopped em todos containers
- [x] Rota Traefik configurada e persistente
- [x] Documentação registrada
