
O Capivara que não cai — espelho no Douglas e o failover que funcionou sozinho
⚡ O hub pessoal que não pode cair
O Capivara é o painel de comando do meu ecossistema: dashboard, health checks dos serviços, Umami, admin de tudo, Segundo Cérebro. Se ele cai, tudo parece morto — mesmo que os outros projetos estejam de pé.
Em agosto de 2026, ele tava devolvendo 502 intermitente no tunnel. Não era um crash — era pior: um downtime invisível, que aparecia e sumia. A resposta foi o princípio arquitetural que vale pra todo o ecossistema: Douglas = espelho + fallback. E pra provar que funcionava, a gente fez o teste mais honesto que existe: derrubou o serviço principal de propósito.
🧠 Contexto — o 502 que ia e voltava
O Capivara roda no Samuel: FastAPI na porta 8001, Cloudflare Tunnel expondo capivara.seu.pet. O Douglas é o PC espelho/fallback do ecossistema — o mesmo papel que já cumpre pro Arachne e pro Dogwalk.
O problema: o tunnel respondia 200/502 alternando. Um healthcheck de passagem pegava 200, outro pegava 502. Pro usuário (eu), era “às vezes funciona”. Pro sistema, era um ponto único de falha sem cobertura.
A regra do ecossistema: se Samuel OU Douglas cair, o site continua de pé. O Capivara ainda não seguia essa regra.
🔧 A luta — montando o espelho
A implementação (Opção A — espelho completo, decidida em 03/08/2026) foi cirúrgica:
- Backend copiado pro Douglas — mesmo path, venv Python 3.13.5 + deps extras (httpx, psutil, pyotp, qrcode, pywebpush, chromadb). O
requirements.txttava desatualizado — a cópia forçou a lista real (commit9477700) - frontend/dist copiado — o SPA inteiro
- Serviço idêntico —
capivara-backend.service(127.0.0.1:8001, EnvironmentFile .env, JWT secret IGUAL — os dois lados aceitam os mesmos tokens) - Tunnel do Douglas —
capivara.seu.pet → 127.0.0.1:8001no cloudflared dele - Sync do banco one-way (Samuel → Douglas), via script dedicado:
# capivara-db-sync-douglas.sh — snapshot consistente mesmo com o app rodando
sqlite3 capivara.db ".backup /tmp/capivara_sync.db" # snapshot
scp /tmp/capivara_sync.db samuel@192.168.7.5:C:/Temp/ # transfere
# no Douglas: para o serviço, troca o db, sobe de novo
- Healthcheck — timer de 5min no Douglas pra garantir que o serviço tá vivo
O sync usa SQLite mode delete (sem WAL) — snapshot via .backup é consistente mesmo com o app escrevendo. Um detalhe que evita corromper o banco no meio da cópia.
Depois de montado, o teste imediato: /health 10/10 = 200 via tunnel com o Douglas ativo (antes: 200/502 alternando).
💡 Resolução — o failover que funcionou sozinho
A prova final foi o teste de failover real: o cloudflared do Samuel foi parado por ~40 segundos. Sem tocar em nada no Douglas.
Resultado:
capivara.seu.pet → 5/5 = 200 (Douglas assumiu SOZINHO)
dogwalk uptime: 61024 → 61104 (prova de que a origem mudou pro Douglas)
religou o cloudflared do Samuel → 5/5 = 200
O detalhe mais bonito: a prova não veio de um log do Capivara — veio do uptime do Dogwalk, que conta de onde a resposta veio. O contador pulou pro Douglas no momento exato do failover e voltou quando o Samuel religou. High availability validada de verdade, não na teoria.
📊 Métricas
| Métrica | Antes | Depois |
|---|---|---|
| Tunnel | 200/502 alternando | 5/5 = 200 estável |
| Failover | não existia | automático (Douglas assume em ~40s) |
| Origem da resposta | Samuel (única) | Samuel + Douglas (espelho) |
| Sync DB | não existia | one-way Samuel → Douglas (cron 1h) |
| Healthcheck | — | timer 5min no Douglas |
| Uptime Dogwalk | origem única | 61024→61104 (prova de troca) |
🎯 Aprendizados
- Disponibilidade se PROVA, não se promete — o teste de failover real (derrubar o principal e ver o espelho assumir) vale mais que qualquer arquitetura documentada.
- O espelho precisa ser idêntico até no secret — JWT secret igual nos dois lados significa que os tokens do usuário sobrevivem ao failover sem re-login.
- Sync one-way com snapshot consistente —
sqlite3 .backup+ swap evita banco corrompido. SQLite mode delete (sem WAL) simplifica o sync. - A prova pode estar no vizinho — o uptime do Dogwalk provou o failover do Capivara. Observabilidade cruzada entre serviços é um superpoder.