354 lines
8.7 KiB
Markdown
354 lines
8.7 KiB
Markdown
# Backup & Restore System - Guia de Implementação
|
|
|
|
## 📋 Visão Geral
|
|
|
|
Este sistema permite criar, gerenciar e fazer download de backups completos do banco de dados PostgreSQL e arquivos MinIO através de uma interface web integrada ao painel administrativo.
|
|
|
|
## 🎯 Características
|
|
|
|
- ✅ Backup completo do PostgreSQL com `pg_dump`
|
|
- ✅ Backup dos dados do MinIO
|
|
- ✅ Compactação automática em `tar.gz`
|
|
- ✅ Interface intuitiva no painel admin
|
|
- ✅ Download de backups
|
|
- ✅ Remoção de backups antigos
|
|
- ✅ Histórico com datas e tamanhos
|
|
- ✅ Funcionamento multi-ambiente (Docker, Local, Dokploy)
|
|
|
|
## 📁 Estrutura de Arquivos
|
|
|
|
```
|
|
frontend/
|
|
├── src/
|
|
│ ├── app/
|
|
│ │ ├── api/
|
|
│ │ │ └── backup/
|
|
│ │ │ ├── route.ts # POST/GET/DELETE - CRUD de backups
|
|
│ │ │ └── download/
|
|
│ │ │ └── route.ts # GET - Download de backups
|
|
│ │ └── admin/
|
|
│ │ └── configuracoes/
|
|
│ │ └── page.tsx # Interface de configurações com backup
|
|
│ └── components/
|
|
│ └── admin/
|
|
│ └── BackupManager.tsx # Componente UI do gerenciador
|
|
└── .backups/ # Diretório onde os backups são salvos
|
|
```
|
|
|
|
## 🔧 Variáveis de Ambiente Necessárias
|
|
|
|
Adicione ao seu `.env` ou ao `docker-compose.yml`:
|
|
|
|
```env
|
|
# PostgreSQL
|
|
POSTGRES_USER=admin
|
|
POSTGRES_PASSWORD=adminpassword
|
|
POSTGRES_DB=occto_db
|
|
POSTGRES_HOST=postgres
|
|
POSTGRES_PORT=5432
|
|
|
|
# MinIO
|
|
MINIO_ENDPOINT=minio
|
|
MINIO_PORT=9000
|
|
MINIO_ACCESS_KEY=admin
|
|
MINIO_SECRET_KEY=adminpassword
|
|
MINIO_BUCKET_NAME=occto-images
|
|
MINIO_USE_SSL=false
|
|
```
|
|
|
|
## 🚀 Como Usar
|
|
|
|
### 1. **No Painel Admin**
|
|
|
|
1. Acesse `/admin/configuracoes`
|
|
2. Desça até a seção **"Backup & Restauração"**
|
|
3. Clique em **"Criar Backup Agora"** para iniciar um novo backup
|
|
4. Visualize o histórico de backups salvos
|
|
5. Download de um backup específico: clique no ícone de download
|
|
6. Remover um backup: clique no ícone de lixeira
|
|
|
|
### 2. **Via API (Programaticamente)**
|
|
|
|
```javascript
|
|
// Criar backup
|
|
const response = await fetch('/api/backup', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': 'Bearer seu_token_aqui',
|
|
'Content-Type': 'application/json'
|
|
}
|
|
});
|
|
|
|
// Listar backups
|
|
const response = await fetch('/api/backup', {
|
|
headers: {
|
|
'Authorization': 'Bearer seu_token_aqui'
|
|
}
|
|
});
|
|
|
|
// Download de backup
|
|
const response = await fetch('/api/backup/download?file=backup-2025-11-28.tar.gz', {
|
|
headers: {
|
|
'Authorization': 'Bearer seu_token_aqui'
|
|
}
|
|
});
|
|
|
|
// Remover backup
|
|
const response = await fetch('/api/backup?id=backup-2025-11-28', {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'Authorization': 'Bearer seu_token_aqui'
|
|
}
|
|
});
|
|
```
|
|
|
|
## 🏗️ Replicação em Outro Projeto Next.js
|
|
|
|
Se você quer implementar este sistema em outro projeto Next.js:
|
|
|
|
### Passo 1: Copiar os Arquivos
|
|
|
|
```bash
|
|
# Copiar as rotas da API
|
|
cp -r frontend/src/app/api/backup seu_projeto/src/app/api/
|
|
|
|
# Copiar o componente UI
|
|
cp frontend/src/components/admin/BackupManager.tsx seu_projeto/src/components/admin/
|
|
```
|
|
|
|
### Passo 2: Adicionar ao Docker Compose
|
|
|
|
Se estiver usando Docker:
|
|
|
|
```yaml
|
|
services:
|
|
postgres:
|
|
image: postgres:12-alpine
|
|
container_name: seu_postgres
|
|
environment:
|
|
POSTGRES_USER: admin
|
|
POSTGRES_PASSWORD: adminpassword
|
|
POSTGRES_DB: seu_db
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
# Montar diretório de backups
|
|
- ./backups:/app/.backups
|
|
networks:
|
|
- seu_network
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U admin"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
seu_frontend:
|
|
# ... suas configurações
|
|
volumes:
|
|
# Compartilhar diretório de backups
|
|
- ./backups:/app/.backups
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
```
|
|
|
|
### Passo 3: Integrar na Página de Configurações
|
|
|
|
```tsx
|
|
// Sua página de configurações
|
|
import { BackupManager } from '@/components/admin/BackupManager';
|
|
|
|
export default function ConfiguracoesPage() {
|
|
return (
|
|
<div>
|
|
{/* Suas outras configurações */}
|
|
|
|
{/* Adicionar seção de backup */}
|
|
<div className="border-t pt-8 mt-8">
|
|
<h2 className="text-2xl font-bold mb-6">Backup & Restauração</h2>
|
|
<BackupManager />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Passo 4: Autenticação
|
|
|
|
O sistema espera um token no header `Authorization: Bearer token`.
|
|
|
|
Você pode:
|
|
|
|
**Opção A:** Usar o token do usuário logado
|
|
|
|
```typescript
|
|
// No componente BackupManager
|
|
const token = localStorage.getItem('auth_token');
|
|
```
|
|
|
|
**Opção B:** Criar um middleware de autenticação
|
|
|
|
```typescript
|
|
// api/backup/route.ts
|
|
function authenticateRequest(request: NextRequest): boolean {
|
|
const token = request.headers.get('authorization');
|
|
|
|
// Implementar sua lógica de autenticação
|
|
return validateToken(token);
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
if (!authenticateRequest(request)) {
|
|
return NextResponse.json({ error: 'Não autorizado' }, { status: 401 });
|
|
}
|
|
// ... resto do código
|
|
}
|
|
```
|
|
|
|
**Opção C:** Usar autenticação de sessão (exemplo com NextAuth)
|
|
|
|
```typescript
|
|
import { getServerSession } from 'next-auth/next';
|
|
import { authOptions } from '@/app/api/auth/[...nextauth]/route';
|
|
|
|
export async function POST(request: NextRequest) {
|
|
const session = await getServerSession(authOptions);
|
|
|
|
if (!session) {
|
|
return NextResponse.json({ error: 'Não autorizado' }, { status: 401 });
|
|
}
|
|
// ... resto do código
|
|
}
|
|
```
|
|
|
|
## 📊 Estrutura do Backup
|
|
|
|
Um backup `.tar.gz` contém:
|
|
|
|
```
|
|
backup-2025-11-28/
|
|
├── database.sql # Dump completo do PostgreSQL
|
|
├── minio-data/ # Cópia de todos os arquivos do MinIO
|
|
│ └── [arquivos...]
|
|
└── metadata.json # Informações do backup
|
|
{
|
|
"timestamp": "2025-11-28T10:30:45.123Z",
|
|
"database": "occto_db",
|
|
"hostname": "postgres",
|
|
"minioEndpoint": "minio",
|
|
"version": "1.0"
|
|
}
|
|
```
|
|
|
|
## 🔐 Segurança
|
|
|
|
### Recomendações:
|
|
|
|
1. **Autenticação**
|
|
- Sempre valide a autenticação nas rotas de backup
|
|
- Use tokens JWT ou sessões seguras
|
|
|
|
2. **Autorização**
|
|
- Apenas administradores devem ter acesso
|
|
- Adicione verificação de roles/permissões
|
|
|
|
3. **Armazenamento de Backups**
|
|
- Considere armazenar em local protegido
|
|
- Implemente limpeza automática de backups antigos
|
|
- Criptografe backups sensíveis
|
|
|
|
4. **Path Traversal**
|
|
- O código já implementa validação com `path.resolve()`
|
|
- Nunca permita caminhos arbitrários
|
|
|
|
### Exemplo de Middleware de Autorização:
|
|
|
|
```typescript
|
|
import { NextRequest, NextResponse } from 'next/server';
|
|
|
|
function isAdmin(request: NextRequest): boolean {
|
|
const token = request.headers.get('authorization');
|
|
// Validar se o token corresponde a um admin
|
|
return validateAdminToken(token);
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
if (!isAdmin(request)) {
|
|
return NextResponse.json(
|
|
{ error: 'Apenas administradores podem criar backups' },
|
|
{ status: 403 }
|
|
);
|
|
}
|
|
// ... resto do código
|
|
}
|
|
```
|
|
|
|
## 🐛 Troubleshooting
|
|
|
|
### Erro: "pg_dump: comando não encontrado"
|
|
|
|
**Solução:** Certifique-se de que PostgreSQL Tools está instalado no container ou host.
|
|
|
|
```dockerfile
|
|
FROM node:18-alpine
|
|
|
|
# Adicionar PostgreSQL client
|
|
RUN apk add --no-cache postgresql-client
|
|
|
|
WORKDIR /app
|
|
# ... resto do Dockerfile
|
|
```
|
|
|
|
### Erro: "MinIO data não encontrado"
|
|
|
|
**Solução:** Verifique o caminho do volume do MinIO no docker-compose.
|
|
|
|
```yaml
|
|
volumes:
|
|
- ./minio_data:/data # Caminho correto no container
|
|
- ./backups:/app/.backups
|
|
```
|
|
|
|
### Erro 401 "Não autorizado"
|
|
|
|
**Solução:** Verifique se o token está sendo enviado corretamente.
|
|
|
|
```javascript
|
|
// Sempre enviar token
|
|
const token = localStorage.getItem('auth_token');
|
|
if (!token) {
|
|
console.error('Token não encontrado');
|
|
return;
|
|
}
|
|
|
|
fetch('/api/backup', {
|
|
headers: {
|
|
'Authorization': `Bearer ${token}`
|
|
}
|
|
});
|
|
```
|
|
|
|
## 📈 Melhorias Futuras
|
|
|
|
- [ ] Agendamento automático de backups (cron)
|
|
- [ ] Envio automático para S3/Cloud Storage
|
|
- [ ] Compressão em background
|
|
- [ ] Restauração de backups via interface
|
|
- [ ] Notificações via email
|
|
- [ ] Verificação de integridade de backup
|
|
- [ ] Versionamento de backups
|
|
- [ ] Limpeza automática de backups antigos
|
|
|
|
## 📞 Suporte
|
|
|
|
Para mais informações ou dúvidas sobre implementação, consulte a documentação oficial:
|
|
|
|
- [Next.js API Routes](https://nextjs.org/docs/app/building-your-application/routing/route-handlers)
|
|
- [PostgreSQL pg_dump](https://www.postgresql.org/docs/current/app-pgdump.html)
|
|
- [MinIO Client](https://docs.min.io/minio/baremetal/)
|
|
|
|
---
|
|
|
|
**Versão:** 1.0
|
|
**Data:** Novembro 2025
|
|
**Compatibilidade:** Next.js 13.4+ com App Router
|