Files
scoreodonto.com/documentação/arquitetura.md
T
VPS 4 Builder 89f998964f docs: registry de imagens (Etapa 4) — Gitea Container Registry
- REGISTRY.md: login, convenção de nomes, build+push, pull/rollback, gotcha do 499
- arquitetura.md/deploy.md: registry agora ativo (git.clube67.com), não mais 'não existe'

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 08:30:05 +02:00

132 lines
9.3 KiB
Markdown

# Arquitetura ScoreOdonto — Estado REAL
> Documento de **estado atual verificado** (16/jun/2026). Descreve apenas o que existe e está rodando hoje.
> Sem referências históricas, sem staging, sem listeners desativados. Para o fluxo-alvo de deploy ver `deploy.md`; para o passo a passo operacional ver `DEPLOY-PRODUCAO.md`.
---
## 1. Visão geral
O ScoreOdonto roda sobre **3 VPS** ligadas por uma rede privada **WireGuard** (`10.99.0.0/24`):
| VPS | IP interno | Papel |
|------|-------------|-------------------------------|
| VPS1 | 10.99.0.1 | **Produção** (borda + apps) |
| VPS3 | 10.99.0.3 | **Dados & Controle** (Postgres, Gitea) |
| VPS4 | 10.99.0.4 | **Desenvolvimento & Builder** |
```
Internet (HTTPS)
┌──────────────────────────── VPS1 (10.99.0.1) ─────────────────────────────┐
│ Traefik (TLS Let's Encrypt, entrypoint websecure) │
│ • scoreodonto.com / www ─────► containers de PRODUÇÃO (local) │
│ • dev.scoreodonto.com ─────► http://10.99.0.4:8020 (via WireGuard) │
│ │
│ Produção (imagens buildadas): │
│ scoreodontocom-scoreodonto-frontend-1 (SPA em nginx) │
│ scoreodontocom-scoreodonto-backend-1 (Node :8018) │
│ (também hospeda: rx, newwhats, subdominio, mercado) │
└────────────────────────────────┬──────────────────────────────────────────┘
│ WireGuard
┌───────────────────────┼───────────────────────┐
▼ ▼
┌──── VPS3 (10.99.0.3) ────┐ ┌──── VPS4 (10.99.0.4) ──────────┐
│ PostgreSQL :5432 │◄────────────│ Desenvolvimento + Builder │
│ db: scoreodonto │ (dev E │ nginx (borda dev) :8020→80 │
│ Dragonfly :6379 (/1) │ prod │ └─► frontend :3013 │
│ NATS :4222 │ usam o │ └─► backend (/api):8018 │
│ Temporal :7233 │ MESMO │ Código-fonte em: │
│ Gitea :3000 │ banco) │ /home/deploy/stack/ │
│ repo: ruicesar/ │ │ scoreodonto.com/ │
│ scoreodonto.com │ │ Docker: socket ROOT │
│ Registry: NÃO existe │ │ (/var/run/docker.sock) │
│ (porta 5000 fechada) │ │ │
└───────────────────────────┘ └─────────────────────────────────┘
```
---
## 2. VPS1 — Produção (10.99.0.1)
- **Traefik** (container `traefik-traefik-1`) é a borda: termina TLS (Let's Encrypt, resolver `le`, entrypoint `websecure`) e roteia por `Host`.
- `scoreodonto.com` e `www.scoreodonto.com` → containers de produção locais.
- `dev.scoreodonto.com``http://10.99.0.4:8020` (encaminha para a VPS4 pela WireGuard). Config dinâmica em `traefik/dynamic/dev.scoreodonto.yml`.
- **Containers de produção** (imagens já buildadas, project `scoreodontocom`):
- `scoreodontocom-scoreodonto-frontend-1` — SPA React servido por nginx.
- `scoreodontocom-scoreodonto-backend-1` — API Node/Express na porta `8018`.
- **Docker rootless**: o daemon roda no socket do usuário `deploy` (`unix:///run/user/1000/docker.sock`). Comandos `docker` na VPS1 precisam dessa variável `DOCKER_HOST`.
- Produção **não builda** o ScoreOdonto: ela sobe imagens prontas. (O `docker-compose.yml` tem `build:`, mas o fluxo correto é trazer a imagem pronta da VPS4 — ver `deploy.md`.)
## 3. VPS3 — Dados & Controle (10.99.0.3)
Serviços instalados **direto no host** (não em container):
- **PostgreSQL** `:5432` — banco `scoreodonto`, usuário `scoreodonto_user`. **Fonte de dados única.**
- **DragonflyDB** `:6379` — cache (índice `/1` reservado ao ScoreOdonto).
- **NATS** `:4222` e **Temporal** `:7233` — mensageria / workflows.
- **Gitea** `:3000`**fonte oficial da verdade do código**. Repo `ruicesar/scoreodonto.com`, acesso por `ssh://git@10.99.0.3/ruicesar/scoreodonto.com.git`. É o motor de CI/CD (ver `deploy.md`).
- **Registry de imagens:** o **Container Registry embutido do Gitea** está ativo e em uso, acessível via HTTPS em `git.clube67.com` (namespace `ruicesar/`). Não há `registry:2` separado. Ver `REGISTRY.md`.
## 4. VPS4 — Desenvolvimento & Builder (10.99.0.4)
- **Esta é a máquina de trabalho.** Código-fonte em `/home/deploy/stack/scoreodonto.com/`.
- **Docker é ROOT** aqui (socket `/var/run/docker.sock`) — diferente da VPS1.
- Containers em execução (project `scoreodontocom`):
- `scoreodontocom-nginx-1` — borda do dev, publica `0.0.0.0:8020->80`. É o alvo do Traefik para `dev.scoreodonto.com`.
- `scoreodontocom-scoreodonto-frontend-1` — SPA (porta interna `3013`).
- `scoreodontocom-scoreodonto-backend-1` — API Node (porta interna `8018`).
- **O dev NÃO é Vite HMR.** O container de frontend roda uma **imagem buildada** (`vite build``nginx:alpine`); editar `frontend/` ou `backend/` exige **rebuild + recreate** do container para refletir em `dev.scoreodonto.com`. (Existe um override `docker-compose.dev.yml` com Vite/HMR, mas não é o que está no ar.)
- O `nginx/default.conf` da VPS4 faz: `/api/` e `/socket.io/``scoreodonto-backend:8018`; `/``scoreodonto-frontend:3013`.
### Caminho de uma requisição
- **Produção:** navegador → `https://scoreodonto.com` → Traefik (VPS1, TLS) → frontend/backend de produção (VPS1) → Postgres (VPS3).
- **Dev:** navegador → `https://dev.scoreodonto.com` → Traefik (VPS1, TLS) → `10.99.0.4:8020` (nginx VPS4) → frontend/backend de dev (VPS4) → **mesmo Postgres** (VPS3).
---
## 5. ⚠️ Banco compartilhado entre DEV e PROD
**Dev e produção apontam para o MESMO banco `scoreodonto` na VPS3.** O backend de dev usa `DATABASE_URL=postgresql://scoreodonto_user:<senha>@10.99.0.3:5432/scoreodonto`.
Consequências práticas:
- Migrações rodadas no boot do backend de dev **já alteram o banco real**. As migrações do projeto são **idempotentes e aditivas** (só criam tabelas/colunas), o que torna isso tolerável — mas **não há isolamento**.
- A **única rede de segurança** é o backup (`pg_dump scoreodonto -Fc`) antes de mudanças sensíveis.
- Isolar um banco `scoreodonto_dev` é o conserto estrutural recomendado para o futuro (fora do escopo deste documento).
---
## 6. Stack técnica e portas
| Componente | Tecnologia | Porta interna |
|------------|-----------|----------------|
| Frontend | React + Vite + TypeScript + Tailwind (build estático servido por nginx) | 3013 |
| Backend | Node.js + Express + driver `pg` nativo (**sem ORM**) | 8018 |
| Borda dev (VPS4) | nginx:alpine | 8020 → 80 |
| Banco | PostgreSQL 18 | 5432 |
| Cache | DragonflyDB (índice `/1`) | 6379 |
| Mensageria | NATS / Temporal | 4222 / 7233 |
| Git/CI | Gitea | 3000 |
| Borda prod | Traefik (TLS Let's Encrypt) | 443 (websecure) |
**Imagens (Dockerfiles):**
- Frontend: multi-stage — `node:20-alpine` (build `npm run build`) → `nginx:alpine` (serve `dist/`).
- Backend: `node:20-slim`, `npm install --omit=dev`, `CMD node server.js`.
---
## 7. Versionamento (estado atual e limitação)
- A versão vive em `frontend/constants.ts` (`APP_VERSION`, hoje `V1.0.12`) e é incrementada (patch) por `update-version.js` antes do build.
- **Limitação crítica:** a versão **não aparece** no HTML servido — fica embutida no bundle `index-<hash>.js`. Hoje só dá para saber a versão no ar inspecionando o container. É por isso que não se consegue confirmar "subiu mesmo?" pelo navegador. **Tornar a versão visível** (rodapé + endpoint + log de boot) é uma melhoria planejada (ver lista de afazeres / `deploy.md`).
---
## 8. O que NÃO existe (para encerrar fantasmas)
-**Não existe staging.** Não há `staging.scoreodonto.com`, nem stack `*-staging`, nem banco `scoreodonto_staging`. O único ambiente de teste é `dev.scoreodonto.com` (VPS4), com o banco de produção.
-**Não existe listener de deploy ativo** para o scoreodonto.com. O antigo `listener-scoreodonto.js` (porta 9002) foi deletado e o serviço está desligado; não há webhook do scoreodonto.com registrado no Gitea. Hoje, `git push` **não dispara** deploy automático. (O fluxo-alvo para reativar isso está em `deploy.md`.)
-**Registry:** existe e está em uso — é o Container Registry embutido do Gitea (`git.clube67.com`), não um serviço separado. Ver `REGISTRY.md`.