@sysnee/pgs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +314 -0
- package/docker-compose.yml +16 -0
- package/docs/ARCHITECTURE_RECOMMENDATIONS.md +480 -0
- package/docs/CRITICAL_REVIEW.md +748 -0
- package/docs/EXECUTIVE_SUMMARY.md +210 -0
- package/docs/PROJECT.md +250 -0
- package/haproxy-lua/pg-route.lua +177 -0
- package/manager.js +510 -0
- package/manifest.json +32 -0
- package/package.json +24 -0
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
# Recomendações de Arquitetura para Produção
|
|
2
|
+
|
|
3
|
+
## Resumo Executivo
|
|
4
|
+
|
|
5
|
+
Para transformar esta solução em um produto comercial viável (PaaS de PostgreSQL), os principais gaps são:
|
|
6
|
+
|
|
7
|
+
1. **Orquestração**: Docker Compose não escala → Kubernetes necessário
|
|
8
|
+
2. **Alta Disponibilidade**: Sem replicação → Patroni/pg_auto_failover
|
|
9
|
+
3. **Backup/Recovery**: Inexistente → pgBackRest + S3
|
|
10
|
+
4. **Monitoramento**: Básico → Prometheus + Grafana
|
|
11
|
+
5. **Segurança**: Melhorias necessárias → Vault + SSL/TLS
|
|
12
|
+
6. **API**: CLI apenas → REST API completa
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Abordagem por Fase
|
|
17
|
+
|
|
18
|
+
### FASE 1: MVP Comercial (Docker Compose Melhorado)
|
|
19
|
+
|
|
20
|
+
**Objetivo**: Lançar produto funcional em 2-3 meses
|
|
21
|
+
|
|
22
|
+
**Mudanças Críticas:**
|
|
23
|
+
|
|
24
|
+
#### 1. Arquitetura Multi-Host com Sharding
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
Host 1 (Região A)
|
|
28
|
+
├── docker-compose-1.yml # Tenants 1-50
|
|
29
|
+
└── docker-compose-2.yml # Tenants 51-100
|
|
30
|
+
|
|
31
|
+
Host 2 (Região A)
|
|
32
|
+
├── docker-compose-3.yml # Tenants 101-150
|
|
33
|
+
└── docker-compose-4.yml # Tenants 151-200
|
|
34
|
+
|
|
35
|
+
Load Balancer (HAProxy/Nginx)
|
|
36
|
+
├── Roteia para host correto baseado em tenant_id hash
|
|
37
|
+
└── Health checks de todos os hosts
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Implementação:**
|
|
41
|
+
- API centralizada gerencia distribuição
|
|
42
|
+
- Hash do tenant_id determina qual host
|
|
43
|
+
- Migração de tenant entre hosts possível
|
|
44
|
+
|
|
45
|
+
#### 2. Backup Automatizado
|
|
46
|
+
|
|
47
|
+
```yaml
|
|
48
|
+
# Por tenant, adicionar service de backup
|
|
49
|
+
backup_${tenantId}:
|
|
50
|
+
image: postgres:18
|
|
51
|
+
volumes:
|
|
52
|
+
- pgdata_${tenantId}:/backup-source:ro
|
|
53
|
+
- backup_${tenantId}:/backups
|
|
54
|
+
command: |
|
|
55
|
+
while true; do
|
|
56
|
+
pg_dump -h pgs_${tenantId} -U postgres ${tenantId} | \
|
|
57
|
+
gzip > /backups/backup-$(date +%Y%m%d-%H%M%S).sql.gz
|
|
58
|
+
# Upload para S3
|
|
59
|
+
aws s3 sync /backups s3://backups/${tenantId}/
|
|
60
|
+
# Manter apenas últimos 7 dias local
|
|
61
|
+
find /backups -mtime +7 -delete
|
|
62
|
+
sleep 86400 # 24 horas
|
|
63
|
+
done
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### 3. API REST
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
// Estrutura proposta
|
|
70
|
+
/api/v1/
|
|
71
|
+
tenants/
|
|
72
|
+
POST # Criar tenant
|
|
73
|
+
GET # Listar tenants
|
|
74
|
+
GET /:id # Detalhes tenant
|
|
75
|
+
DELETE /:id # Remover tenant
|
|
76
|
+
POST /:id/backup # Backup manual
|
|
77
|
+
POST /:id/restore # Restaurar
|
|
78
|
+
GET /:id/metrics # Métricas
|
|
79
|
+
POST /:id/scale # Mudar plano
|
|
80
|
+
health/
|
|
81
|
+
GET # Status geral
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### 4. Secrets Management (Básico)
|
|
85
|
+
|
|
86
|
+
```yaml
|
|
87
|
+
# Usar Docker Secrets ou Vault básico
|
|
88
|
+
services:
|
|
89
|
+
pgs_tenant1:
|
|
90
|
+
secrets:
|
|
91
|
+
- db_password
|
|
92
|
+
secrets:
|
|
93
|
+
db_password:
|
|
94
|
+
external: true
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### 5. Monitoring Básico
|
|
98
|
+
|
|
99
|
+
```yaml
|
|
100
|
+
# Adicionar Prometheus + Grafana
|
|
101
|
+
prometheus:
|
|
102
|
+
image: prom/prometheus
|
|
103
|
+
volumes:
|
|
104
|
+
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
|
105
|
+
ports:
|
|
106
|
+
- "9090:9090"
|
|
107
|
+
|
|
108
|
+
grafana:
|
|
109
|
+
image: grafana/grafana
|
|
110
|
+
ports:
|
|
111
|
+
- "3000:3000"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Métricas a coletar:**
|
|
115
|
+
- CPU, RAM, Disk por tenant
|
|
116
|
+
- Connections ativas
|
|
117
|
+
- Queries por segundo
|
|
118
|
+
- Backup status
|
|
119
|
+
- Container health
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
### FASE 2: Alta Disponibilidade (3-6 meses)
|
|
124
|
+
|
|
125
|
+
#### 1. Replicação PostgreSQL com Patroni
|
|
126
|
+
|
|
127
|
+
```yaml
|
|
128
|
+
# Estrutura por tenant
|
|
129
|
+
pgs_tenant1_primary:
|
|
130
|
+
image: patroni/patroni
|
|
131
|
+
environment:
|
|
132
|
+
PATRONI_SCOPE: tenant1
|
|
133
|
+
PATRONI_NAME: tenant1-primary
|
|
134
|
+
# Replicação streaming
|
|
135
|
+
|
|
136
|
+
pgs_tenant1_replica:
|
|
137
|
+
image: patroni/patroni
|
|
138
|
+
environment:
|
|
139
|
+
PATRONI_SCOPE: tenant1
|
|
140
|
+
PATRONI_NAME: tenant1-replica
|
|
141
|
+
PATRONI_ROLE: replica
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### 2. HAProxy Redundante
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
HAProxy 1 ──┐
|
|
148
|
+
├── Keepalived VIP (Virtual IP)
|
|
149
|
+
HAProxy 2 ──┘
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### 3. Backup com pgBackRest
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
# Backup service melhorado
|
|
156
|
+
backup_service:
|
|
157
|
+
image: pgbackrest/pgbackrest
|
|
158
|
+
volumes:
|
|
159
|
+
- pgdata:/pgdata:ro
|
|
160
|
+
- backups:/backups
|
|
161
|
+
command: pgbackrest backup --stanza=tenant1
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
### FASE 3: Kubernetes (6-12 meses)
|
|
167
|
+
|
|
168
|
+
#### Estrutura Kubernetes
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
PostgreSQL Operator (Custom ou Postgres Operator)
|
|
172
|
+
├── PostgreSQL Cluster (StatefulSet)
|
|
173
|
+
│ ├── Primary Pod
|
|
174
|
+
│ └── Replica Pods
|
|
175
|
+
├── Service (ClusterIP)
|
|
176
|
+
├── Ingress (para acesso externo)
|
|
177
|
+
└── PersistentVolumeClaim (dados)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
#### Exemplo de StatefulSet
|
|
181
|
+
|
|
182
|
+
```yaml
|
|
183
|
+
apiVersion: apps/v1
|
|
184
|
+
kind: StatefulSet
|
|
185
|
+
metadata:
|
|
186
|
+
name: pgs-${tenantId}
|
|
187
|
+
spec:
|
|
188
|
+
serviceName: pgs-${tenantId}
|
|
189
|
+
replicas: 1 # 2+ para HA
|
|
190
|
+
selector:
|
|
191
|
+
matchLabels:
|
|
192
|
+
app: postgres
|
|
193
|
+
tenant: ${tenantId}
|
|
194
|
+
template:
|
|
195
|
+
metadata:
|
|
196
|
+
labels:
|
|
197
|
+
app: postgres
|
|
198
|
+
tenant: ${tenantId}
|
|
199
|
+
spec:
|
|
200
|
+
containers:
|
|
201
|
+
- name: postgres
|
|
202
|
+
image: postgres:18
|
|
203
|
+
resources:
|
|
204
|
+
requests:
|
|
205
|
+
memory: "256Mi"
|
|
206
|
+
cpu: "100m"
|
|
207
|
+
limits:
|
|
208
|
+
memory: "2Gi"
|
|
209
|
+
cpu: "2000m"
|
|
210
|
+
volumeMounts:
|
|
211
|
+
- name: data
|
|
212
|
+
mountPath: /var/lib/postgresql
|
|
213
|
+
env:
|
|
214
|
+
- name: POSTGRES_DB
|
|
215
|
+
value: ${tenantId}
|
|
216
|
+
- name: POSTGRES_USER
|
|
217
|
+
valueFrom:
|
|
218
|
+
secretKeyRef:
|
|
219
|
+
name: pgs-${tenantId}-secret
|
|
220
|
+
key: username
|
|
221
|
+
- name: POSTGRES_PASSWORD
|
|
222
|
+
valueFrom:
|
|
223
|
+
secretKeyRef:
|
|
224
|
+
name: pgs-${tenantId}-secret
|
|
225
|
+
key: password
|
|
226
|
+
volumeClaimTemplates:
|
|
227
|
+
- metadata:
|
|
228
|
+
name: data
|
|
229
|
+
spec:
|
|
230
|
+
accessModes: [ "ReadWriteOnce" ]
|
|
231
|
+
resources:
|
|
232
|
+
requests:
|
|
233
|
+
storage: 50Gi
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Alternativas ao Docker Compose
|
|
239
|
+
|
|
240
|
+
### Opção 1: Kubernetes (Recomendado)
|
|
241
|
+
|
|
242
|
+
**Vantagens:**
|
|
243
|
+
- Industry standard para produção
|
|
244
|
+
- Auto-scaling nativo
|
|
245
|
+
- Health checks avançados
|
|
246
|
+
- Resource quotas
|
|
247
|
+
- Multi-region
|
|
248
|
+
- Service mesh (Istio/Linkerd)
|
|
249
|
+
|
|
250
|
+
**Desvantagens:**
|
|
251
|
+
- Curva de aprendizado alta
|
|
252
|
+
- Complexidade operacional
|
|
253
|
+
- Custo de infraestrutura (master nodes)
|
|
254
|
+
|
|
255
|
+
**Quando usar:**
|
|
256
|
+
- Produção em escala
|
|
257
|
+
- Multi-region
|
|
258
|
+
- Auto-scaling necessário
|
|
259
|
+
- Enterprise clients
|
|
260
|
+
|
|
261
|
+
### Opção 2: Docker Swarm
|
|
262
|
+
|
|
263
|
+
**Vantagens:**
|
|
264
|
+
- Mais simples que Kubernetes
|
|
265
|
+
- Usa docker-compose.yml
|
|
266
|
+
- Multi-host nativo
|
|
267
|
+
- Service discovery
|
|
268
|
+
|
|
269
|
+
**Desvantagens:**
|
|
270
|
+
- Ecossistema menor
|
|
271
|
+
- Menos features
|
|
272
|
+
- Menos maduro
|
|
273
|
+
|
|
274
|
+
**Quando usar:**
|
|
275
|
+
- Migração de Docker Compose
|
|
276
|
+
- Menos complexidade que K8s
|
|
277
|
+
- Escala média (< 500 tenants)
|
|
278
|
+
|
|
279
|
+
### Opção 3: Nomad (HashiCorp)
|
|
280
|
+
|
|
281
|
+
**Vantagens:**
|
|
282
|
+
- Muito leve
|
|
283
|
+
- Suporta containers, VMs, binaries
|
|
284
|
+
- Simples de operar
|
|
285
|
+
- Bom para multi-cloud
|
|
286
|
+
|
|
287
|
+
**Desvantagens:**
|
|
288
|
+
- Ecossistema menor
|
|
289
|
+
- Menos conhecido
|
|
290
|
+
- Menos integrações
|
|
291
|
+
|
|
292
|
+
**Quando usar:**
|
|
293
|
+
- Infraestrutura HashiCorp existente
|
|
294
|
+
- Multi-cloud
|
|
295
|
+
- Simplicidade prioritária
|
|
296
|
+
|
|
297
|
+
### Opção 4: Docker Compose V2 Melhorado
|
|
298
|
+
|
|
299
|
+
**Melhorias Possíveis:**
|
|
300
|
+
|
|
301
|
+
```yaml
|
|
302
|
+
# docker-compose.yml com profiles e múltiplos arquivos
|
|
303
|
+
services:
|
|
304
|
+
haproxy:
|
|
305
|
+
# ...
|
|
306
|
+
|
|
307
|
+
pgs_tenant1:
|
|
308
|
+
profiles: ["tenants-group-1"]
|
|
309
|
+
# ...
|
|
310
|
+
|
|
311
|
+
pgs_tenant2:
|
|
312
|
+
profiles: ["tenants-group-1"]
|
|
313
|
+
# ...
|
|
314
|
+
|
|
315
|
+
# Separar por arquivos
|
|
316
|
+
# tenants-01-50.yml
|
|
317
|
+
# tenants-51-100.yml
|
|
318
|
+
# tenants-101-150.yml
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Sharding Manual:**
|
|
322
|
+
```
|
|
323
|
+
/hosts
|
|
324
|
+
/host-01
|
|
325
|
+
docker-compose.yml # Tenants 1-50
|
|
326
|
+
/host-02
|
|
327
|
+
docker-compose.yml # Tenants 51-100
|
|
328
|
+
|
|
329
|
+
API centralizada gerencia:
|
|
330
|
+
- Qual host tem qual tenant
|
|
331
|
+
- Migração entre hosts
|
|
332
|
+
- Load balancing
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Stack Tecnológico Recomendado
|
|
338
|
+
|
|
339
|
+
### Para MVP (Fase 1)
|
|
340
|
+
|
|
341
|
+
```
|
|
342
|
+
Orquestração: Docker Compose (melhorado)
|
|
343
|
+
Proxy: HAProxy
|
|
344
|
+
Backup: pg_dump + AWS S3
|
|
345
|
+
Monitoring: Prometheus + Grafana
|
|
346
|
+
Secrets: HashiCorp Vault (básico)
|
|
347
|
+
API: Node.js/Express ou Go
|
|
348
|
+
Database: PostgreSQL 18+
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Para Produção (Fase 3)
|
|
352
|
+
|
|
353
|
+
```
|
|
354
|
+
Orquestração: Kubernetes
|
|
355
|
+
Proxy: Nginx Ingress + HAProxy
|
|
356
|
+
Backup: pgBackRest + S3/GCS
|
|
357
|
+
Monitoring: Prometheus + Grafana + Alertmanager
|
|
358
|
+
Secrets: HashiCorp Vault (completo)
|
|
359
|
+
API: Go (performance) ou Node.js (rapidez)
|
|
360
|
+
Database: PostgreSQL 18+ com Patroni
|
|
361
|
+
High Availability: Patroni + etcd
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## Limites Práticos por Abordagem
|
|
367
|
+
|
|
368
|
+
### Docker Compose
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
Limites:
|
|
372
|
+
- ~50-100 containers por host (dependendo de recursos)
|
|
373
|
+
- 1 host = single point of failure
|
|
374
|
+
- Escala manual (adicionar hosts manualmente)
|
|
375
|
+
|
|
376
|
+
Uso recomendado:
|
|
377
|
+
- < 100 tenants total
|
|
378
|
+
- MVP/Prova de conceito
|
|
379
|
+
- Ambientes de desenvolvimento
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Docker Compose + Multi-Host (Sharding)
|
|
383
|
+
|
|
384
|
+
```
|
|
385
|
+
Limites:
|
|
386
|
+
- ~500-1000 tenants (10-20 hosts)
|
|
387
|
+
- Escala horizontal manual
|
|
388
|
+
- Overhead de gerenciamento
|
|
389
|
+
|
|
390
|
+
Uso recomendado:
|
|
391
|
+
- 100-500 tenants
|
|
392
|
+
- Transição para Kubernetes
|
|
393
|
+
- Clientes enterprise
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Kubernetes
|
|
397
|
+
|
|
398
|
+
```
|
|
399
|
+
Limites:
|
|
400
|
+
- Praticamente ilimitado (teoricamente)
|
|
401
|
+
- Depende de infraestrutura
|
|
402
|
+
- Milhares de tenants possíveis
|
|
403
|
+
|
|
404
|
+
Uso recomendado:
|
|
405
|
+
- > 500 tenants
|
|
406
|
+
- Auto-scaling necessário
|
|
407
|
+
- Produção enterprise
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## Custos Estimados (Cloud)
|
|
413
|
+
|
|
414
|
+
### Por Tenant/Mês (estimativa)
|
|
415
|
+
|
|
416
|
+
**AWS/GCP/Azure:**
|
|
417
|
+
- Container: $10-50 (dependendo do plano)
|
|
418
|
+
- Storage: $0.10/GB
|
|
419
|
+
- Backup: $0.023/GB
|
|
420
|
+
- Network: $0.09/GB egress
|
|
421
|
+
|
|
422
|
+
**Custo base por tenant:**
|
|
423
|
+
- Starter: ~$15-30/mês
|
|
424
|
+
- Professional: ~$50-100/mês
|
|
425
|
+
- Enterprise: ~$200-500/mês
|
|
426
|
+
|
|
427
|
+
**Custos de infraestrutura:**
|
|
428
|
+
- Kubernetes cluster: $100-500/mês (master nodes)
|
|
429
|
+
- Load balancer: $20-100/mês
|
|
430
|
+
- Monitoring: $50-200/mês
|
|
431
|
+
- Backup storage: Variável
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## Checklist de Decisões Arquiteturais
|
|
436
|
+
|
|
437
|
+
### Escalabilidade
|
|
438
|
+
- [ ] Quantos tenants simultâneos?
|
|
439
|
+
- [ ] Crescimento esperado?
|
|
440
|
+
- [ ] Multi-region necessário?
|
|
441
|
+
|
|
442
|
+
### Alta Disponibilidade
|
|
443
|
+
- [ ] SLA alvo? (99.9%, 99.99%?)
|
|
444
|
+
- [ ] RTO/RPO definidos?
|
|
445
|
+
- [ ] Budget para HA?
|
|
446
|
+
|
|
447
|
+
### Segurança
|
|
448
|
+
- [ ] Compliance requirements? (GDPR, SOC2, HIPAA)
|
|
449
|
+
- [ ] Encryption requirements?
|
|
450
|
+
- [ ] Audit requirements?
|
|
451
|
+
|
|
452
|
+
### Operações
|
|
453
|
+
- [ ] Equipe técnica disponível?
|
|
454
|
+
- [ ] Expertise em Kubernetes?
|
|
455
|
+
- [ ] Budget para infraestrutura?
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
## Próximos Passos Imediatos
|
|
460
|
+
|
|
461
|
+
1. **Definir MVP Scope**
|
|
462
|
+
- Quantos tenants no lançamento?
|
|
463
|
+
- Quais features essenciais?
|
|
464
|
+
- SLA inicial?
|
|
465
|
+
|
|
466
|
+
2. **Escolher Abordagem Fase 1**
|
|
467
|
+
- Docker Compose melhorado? ✅ Recomendado para MVP
|
|
468
|
+
- Ou pular direto para Kubernetes?
|
|
469
|
+
|
|
470
|
+
3. **Implementar Essenciais**
|
|
471
|
+
- Backup automático
|
|
472
|
+
- API REST
|
|
473
|
+
- Monitoring básico
|
|
474
|
+
- Secrets management
|
|
475
|
+
|
|
476
|
+
4. **Planejar Migração**
|
|
477
|
+
- Roadmap para Kubernetes
|
|
478
|
+
- Estratégia de migração
|
|
479
|
+
- Timeline
|
|
480
|
+
|