feat(infraestrutura): adiciona plugin infraestrutura (agents, skills, knowledge e metadados do projeto)

This commit is contained in:
2026-10-28 16:09:01 +00:00
parent de2d6f2fb5
commit e43fec3bd9
73 changed files with 8589 additions and 0 deletions
@@ -0,0 +1,165 @@
---
name: backup-strategies
description: Planeamento e implementacao de estrategias de backup -- bases de dados, ficheiros e configuracoes com RPO/RTO e regra 3-2-1.
layer: wiki
---
# /backup-strategies - Backup e Disaster Recovery
Implementacao de estrategias de backup completas seguindo best practices de RPO/RTO e regra 3-2-1.
---
## Quando usar
- Planear estrategia de backup para novo projecto
- Implementar backup automatizado
- Configurar disaster recovery
- Definir politicas de retencao
- Testar procedimentos de restore
- Auditar backups existentes
- Recuperar de falha/corrupcao
---
## Conceitos core
### RPO vs RTO
```
RPO (Recovery Point Objective)
= Maximo de dados que pode perder
= Frequencia minima de backups
RTO (Recovery Time Objective)
= Tempo maximo para restaurar
= Define tipo de solucao DR
```
**Tabela de decisao:**
| Criticidade | RPO | RTO | Solucao | Custo |
|-------------|-----|-----|---------|-------|
| **Critico** | 0 | <1h | Replicacao real-time + hot standby | Alto |
| **Alto** | 1h | <4h | Backup horario + warm standby | Medio-alto |
| **Medio** | 24h | <24h | Backup diario + cold backup | Medio |
| **Baixo** | 7d | <72h | Backup semanal | Baixo |
### Regra 3-2-1
- **3** copias dos dados (producao + backup local + backup offsite)
- **2** tipos de media diferentes (disco local + cloud)
- **1** copia offsite (protege contra desastres locais)
**Implementacao Descomplicar (estado real — fonte de verdade: `Hub/05-Projectos/SistemaBackups/`):**
1. **Producao:** Servidor CWP (VM 100) + EasyPanel (VM 101) no cluster Proxmox
2. **Backup:** Proxmox vzdump → PBS (6TB) + MySQL hourly + rsync servidores → cluster
3. **Offsite:** **pendente** (regra 3-2-1 em 2-1-0; decisao Hetzner Storage Box / Backblaze B2 / Wasabi). Insync/rclone→GDrive estao mortos — nao assumir como activos.
> Esta skill cobre conceitos genericos (RPO/RTO, GFS, 3-2-1). Para o estado e topologia reais do sistema Descomplicar, consultar sempre `Hub/05-Projectos/SistemaBackups/AUDITORIA-Backups-2026-06-08.md`.
---
## Workflow principal
### Passo 1: Definir RPO/RTO
Classificar cada sistema pela tabela de criticidade acima.
### Passo 2: Implementar scripts
Scripts prontos para MySQL, WordPress, CWP e rotacao GFS:
**-> [references/scripts.md](references/scripts.md)**
Inclui:
- Backup MySQL com `--single-transaction` e compressao
- Backup PostgreSQL com `pg_dump`
- Backup incremental MySQL com binlog
- Backup WordPress completo (com exclusoes inteligentes)
- Backup incremental com rsync
- Backup contas e configuracoes CWP
- Rotacao GFS (Grandfather-Father-Son)
- Cron schedule completo
- Cloud sync com rclone
- Script teste de restore
- Runbook disaster recovery
### Passo 3: Configurar retencao GFS
| Tipo | Retencao | Frequencia | Slots |
|------|----------|------------|-------|
| **Horario** | 24h | A cada hora | 24 |
| **Diario** | 7 dias | 1x/dia (00:00) | 7 |
| **Semanal** | 4 semanas | 1x/semana (domingo) | 4 |
| **Mensal** | 12 meses | 1x/mes (dia 1) | 12 |
| **Anual** | 7 anos | 1x/ano (1 janeiro) | 7 |
**Total:** 54 backups simultaneos
### Passo 4: Automatizar com cron
Ver schedule completo em `references/scripts.md` (seccao Cron Schedule).
### Passo 5: Configurar cloud sync
Configurar rclone para sync automatico. Ver detalhes em `references/scripts.md`.
### Passo 6: Testar restore (mensal obrigatorio)
Executar script de teste de restore mensalmente. Ver script em `references/scripts.md`.
---
## Disaster recovery
### Checklist DR
- [ ] Backups testados (restore funciona?)
- [ ] Documentacao actualizada (runbook)
- [ ] Runbook de recovery acessivel offline
- [ ] Contactos de emergencia definidos
- [ ] Acesso offsite confirmado (credenciais)
- [ ] Teste DR trimestral agendado
- [ ] RTO/RPO documentados
- [ ] Plano de comunicacao (clientes/equipa)
### Runbook
Ver runbook completo passo-a-passo em `references/scripts.md` (seccao Runbook Disaster Recovery).
**RTO total estimado:** 4-6 horas
---
## Anti-patterns
| Anti-pattern | Problema | Solucao |
|--------------|----------|---------|
| Backup sem teste | Pode falhar no restore | Teste mensal obrigatorio |
| Apenas local | Perda em desastre | Regra 3-2-1 (offsite obrigatorio) |
| Sem encriptacao | Dados expostos | Encriptar backups sensiveis |
| Manual | Esquecimento humano | Automatizar via cron |
| Sem alertas | Falhas nao detectadas | Monitorizacao + notificacoes |
| Password no comando | Inseguro (history, ps) | Usar .my.cnf ou variaveis ENV |
| Backup sem rotacao | Disco cheio | Script de rotacao automatico |
| Sem documentacao | Caos em emergencia | Runbook DR actualizado |
---
## Checklist de implementacao
### Planeamento
- [ ] RPO/RTO definidos por sistema
- [ ] Regra 3-2-1 implementada
- [ ] Politica de retencao GFS
- [ ] Budget aprovado (storage, cloud)
### Automacao
- [ ] Scripts de backup criados
- [ ] Cron jobs configurados
- [ ] Rotacao automatica activa
- [ ] Cloud sync activo (rclone)
### Seguranca
- [ ] Encriptacao em backups se
@@ -0,0 +1,297 @@
# /backup-strategies - Scripts e Automação
Scripts prontos a usar para backup e disaster recovery.
## MySQL - Dump com Compressão
```bash
#!/bin/bash
# backup-mysql.sh
DB_NAME="ealmeida_desk24"
DB_USER="root"
DB_PASS="PASSWORD" # Usar ficheiro .my.cnf na prática
BACKUP_DIR="/backups/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
mkdir -p "$BACKUP_DIR"
mysqldump \
--single-transaction \
--routines \
--triggers \
--events \
--hex-blob \
-u "$DB_USER" \
-p"$DB_PASS" \
"$DB_NAME" | gzip -9 > "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz"
if [ $? -eq 0 ]; then
SIZE=$(du -h "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz" | cut -f1)
echo "Backup $DB_NAME: $SIZE"
else
echo "ERRO ao fazer backup de $DB_NAME"
exit 1
fi
find "$BACKUP_DIR" -name "${DB_NAME}_*.sql.gz" -mtime +$RETENTION_DAYS -delete
```
**Opções Críticas:**
- `--single-transaction`: Consistência sem lock (InnoDB)
- `--routines`: Incluir stored procedures
- `--hex-blob`: Formato binário seguro para BLOBs
**Anti-Patterns:**
- `mysqldump database > backup.sql` sem `--single-transaction`
- Backup sem compressão
- Password na linha de comando
## PostgreSQL - pg_dump
```bash
# Backup com compressão máxima
pg_dump -Fc -Z9 -d database_name > backup_$(date +%Y%m%d_%H%M%S).dump
# Backup de cluster completo
pg_dumpall -c | gzip > cluster_backup_$(date +%Y%m%d).sql.gz
```
## Backup Incremental MySQL com Binlog
```bash
# Activar binlog (my.cnf):
# [mysqld]
# log-bin=/var/log/mysql/mysql-bin.log
# expire_logs_days=7
mysqlbinlog --read-from-remote-server --host=localhost \
--start-datetime="2026-02-03 00:00:00" \
mysql-bin.000001 > incremental_backup.sql
```
---
## Backup WordPress
### Backup Completo
```bash
#!/bin/bash
# backup-wordpress.sh
SITE_NAME="emanuelalmeida"
SITE_PATH="/home/ealmeida/emanuelalmeida.pt"
BACKUP_DIR="/backups/wordpress"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
tar -czf "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" \
--exclude='wp-content/cache' \
--exclude='wp-content/uploads/cache' \
--exclude='wp-content/upgrade' \
--exclude='*.log' \
-C "$(dirname $SITE_PATH)" \
"$(basename $SITE_PATH)"
if [ -f "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" ]; then
tar -tzf "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Backup OK e verificado"
else
echo "Arquivo corrompido!"
exit 1
fi
fi
find "$BACKUP_DIR" -name "${SITE_NAME}_*.tar.gz" -mtime +7 -delete
```
### Backup Incremental com rsync
```bash
#!/bin/bash
SOURCE="/home/ealmeida/emanuelalmeida.pt"
BACKUP_BASE="/backups/incremental"
DATE=$(date +%Y%m%d)
rsync -avz --delete \
--backup --backup-dir="$BACKUP_BASE/delta/$DATE" \
--exclude='wp-content/cache' \
"$SOURCE/" "$BACKUP_BASE/current/"
```
---
## Backup Servidor CWP
### Backup Conta CWP
```bash
/usr/local/cwpsrv/htdocs/resources/scripts/backup_accounts \
--account=username \
--type=full \
--destination=/backups/cwp
```
### Backup Configurações Servidor
```bash
#!/bin/bash
BACKUP_DIR="/backups/config"
DATE=$(date +%Y%m%d_%H%M%S)
tar -czf "$BACKUP_DIR/server_config_${DATE}.tar.gz" \
/etc/nginx \
/etc/apache2 \
/etc/mysql \
/etc/my.cnf \
/etc/php* \
/usr/local/cwpsrv/conf \
/root/.acme.sh/cwp_certs \
/etc/cron* \
/etc/fstab \
/etc/hosts
```
---
## Rotação GFS (Grandfather-Father-Son)
```bash
#!/bin/bash
BACKUP_DIR="/backups"
HOURLY_KEEP=24
DAILY_KEEP=7
WEEKLY_KEEP=4
MONTHLY_KEEP=12
find "$BACKUP_DIR/hourly" -mtime +1 -delete
find "$BACKUP_DIR/daily" -mtime +$DAILY_KEEP -delete
find "$BACKUP_DIR/weekly" -mtime +$((WEEKLY_KEEP * 7)) -delete
find "$BACKUP_DIR/monthly" -mtime +$((MONTHLY_KEEP * 30)) -delete
du -sh "$BACKUP_DIR"/*
```
| Tipo | Retenção | Frequência |
|------|----------|------------|
| Horário | 24h | A cada hora |
| Diário | 7 dias | 1x/dia (00:00) |
| Semanal | 4 semanas | 1x/semana |
| Mensal | 12 meses | 1x/mês |
---
## Cron Schedule
```cron
# Backup MySQL (diário às 02:00)
0 2 * * * /root/scripts/backup-mysql.sh >> /var/log/backup-mysql.log 2>&1
# Backup WordPress (diário às 03:00)
0 3 * * * /root/scripts/backup-wordpress.sh >> /var/log/backup-wp.log 2>&1
# Backup configurações (semanal, domingo 04:00)
0 4 * * 0 /root/scripts/backup-server-config.sh >> /var/log/backup-config.log 2>&1
# Rotação backups (diário às 05:00)
0 5 * * * /root/scripts/backup-rotation-gfs.sh >> /var/log/backup-rotation.log 2>&1
# Teste de restore (mensal, dia 1 às 06:00)
0 6 1 * * /root/scripts/test-restore.sh >> /var/log/test-restore.log 2>&1
# Sync para cloud (diário às 07:00)
0 7 * * * rclone sync /backups gdrive:backups >> /var/log/rclone-sync.log 2>&1
```
---
## Cloud Sync com rclone
```bash
# Instalar rclone
curl https://rclone.org/install.sh | sudo bash
# Configurar Google Drive
rclone config
# Nome: gdrive | Tipo: drive | Seguir wizard
```
```bash
#!/bin/bash
LOCAL_DIR="/backups"
REMOTE="gdrive:backups"
rclone sync "$LOCAL_DIR" "$REMOTE" \
--exclude "*.tmp" \
--exclude "*.log" \
--progress
```
---
## Teste de Restore (OBRIGATÓRIO Mensal)
```bash
#!/bin/bash
TEST_DB="test_restore_$(date +%Y%m%d)"
BACKUP_FILE="/backups/mysql/ealmeida_desk24_latest.sql.gz"
mysql -e "CREATE DATABASE $TEST_DB;"
gunzip < "$BACKUP_FILE" | mysql "$TEST_DB"
TABLES=$(mysql -Nse "SELECT COUNT(*) FROM information_schema.TABLES WHERE table_schema='$TEST_DB';")
echo "Tabelas restauradas: $TABLES"
mysqlcheck --check "$TEST_DB" | grep -i error
mysql -e "DROP DATABASE $TEST_DB;"
echo "Teste concluído"
```
---
## Runbook Disaster Recovery
```markdown
# DISASTER RECOVERY RUNBOOK
## Cenário: Servidor CWP Inoperacional
### Passo 1: Avaliação (5 min)
- [ ] Confirmar que servidor não responde (ping, SSH)
- [ ] Identificar tipo de falha (hardware, software, ataque)
- [ ] Comunicar clientes afectados (se downtime >1h)
### Passo 2: Provisionar Servidor (30 min)
- [ ] Ubuntu 22.04 ou CentOS 7
- [ ] Instalar CWP: `sh cwp-el7-latest.sh`
- [ ] Configurar firewall e SSH
### Passo 3: Restore Bases de Dados (1-2h)
```bash
gunzip ealmeida_desk24_20260203_120000.sql.gz
mysql -e "CREATE DATABASE ealmeida_desk24;"
mysql ealmeida_desk24 < ealmeida_desk24_20260203_120000.sql
```
### Passo 4: Restore Ficheiros (1-2h)
```bash
tar -xzf wordpress_sites_20260203.tar.gz -C /tmp/
cp -r /tmp/emanuelalmeida.pt /home/ealmeida/
chown -R ealmeida:ealmeida /home/ealmeida/emanuelalmeida.pt
```
### Passo 5: Validação (30 min)
- [ ] Testar acesso SSH
- [ ] MySQL a responder
- [ ] Sites WordPress a carregar
- [ ] SSL activo
**RTO Total Estimado:** 4-6 horas
```