8.7 KiB
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:
# 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
- Acesse
/admin/configuracoes - Desça até a seção "Backup & Restauração"
- Clique em "Criar Backup Agora" para iniciar um novo backup
- Visualize o histórico de backups salvos
- Download de um backup específico: clique no ícone de download
- Remover um backup: clique no ícone de lixeira
2. Via API (Programaticamente)
// 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
# 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:
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
// 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
// No componente BackupManager
const token = localStorage.getItem('auth_token');
Opção B: Criar um middleware de autenticação
// 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)
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:
-
Autenticação
- Sempre valide a autenticação nas rotas de backup
- Use tokens JWT ou sessões seguras
-
Autorização
- Apenas administradores devem ter acesso
- Adicione verificação de roles/permissões
-
Armazenamento de Backups
- Considere armazenar em local protegido
- Implemente limpeza automática de backups antigos
- Criptografe backups sensíveis
-
Path Traversal
- O código já implementa validação com
path.resolve() - Nunca permita caminhos arbitrários
- O código já implementa validação com
Exemplo de Middleware de Autorização:
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.
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.
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.
// 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:
Versão: 1.0
Data: Novembro 2025
Compatibilidade: Next.js 13.4+ com App Router