Pular para o conteúdo principal

Backup e Recovery

Este documento ensina como implementar backup e recovery para n8n, incluindo backup automático de workflows, export/import de credenciais, versionamento de configurações, recuperação point-in-time, testes de restauração, e estratégias de disaster recovery que garantem proteção completa dos dados críticos e continuidade operacional mesmo em cenários catastróficos de perda de dados ou infraestrutura.


Estratégia 3-2-1

Implemente a estratégia 3-2-1 para proteção máxima:

  • 3 cópias dos dados
  • 2 tipos de mídia diferentes
  • 1 cópia fora do local

Backup de Banco de Dados

PostgreSQL

#!/bin/bash

# Configurações
DB_HOST="localhost"
DB_PORT="5432"
DB_NAME="n8n"
DB_USER="n8n"
DB_PASSWORD="n8n"
BACKUP_DIR="/backups/n8n/database"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/n8n_db_$DATE.sql"
RETENTION_DAYS=30

echo "Iniciando backup do PostgreSQL..."
pg_dump -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME > $BACKUP_FILE

if [ $? -eq 0 ]; then
    echo "Backup criado com sucesso: $BACKUP_FILE"
    
    # Comprimir backup
    gzip $BACKUP_FILE
    echo "Backup comprimido: $BACKUP_FILE.gz"
    
    # Calcular tamanho do backup
    BACKUP_SIZE=$(du -h "$BACKUP_FILE.gz" | cut -f1)
    echo "Tamanho do backup: $BACKUP_SIZE"
    
    # Remover backups antigos
    find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
    echo "Backups antigos removidos (mais de $RETENTION_DAYS dias)"
    
    # Log do backup
    echo "$(date): Backup PostgreSQL criado - $BACKUP_FILE.gz ($BACKUP_SIZE)" >> /var/log/n8n/backup.log
else
    echo "ERRO: Falha no backup do PostgreSQL"
    exit 1
fi

Backup Incremental

#!/bin/bash

# Configurações
DB_HOST="localhost"
DB_PORT="5432"
DB_NAME="n8n"
DB_USER="n8n"
BACKUP_DIR="/backups/n8n/database/incremental"
DATE=$(date +%Y%m%d_%H%M%S)

echo "Iniciando backup incremental..."
pg_basebackup -h $DB_HOST -p $DB_PORT -U $DB_USER -D $BACKUP_DIR/base_$DATE

echo "Backup incremental criado: $BACKUP_DIR/base_$DATE"

MySQL

#!/bin/bash

# Configurações
DB_HOST="localhost"
DB_PORT="3306"
DB_NAME="n8n"
DB_USER="n8n"
DB_PASSWORD="n8n"
BACKUP_DIR="/backups/n8n/database"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/n8n_db_$DATE.sql"
RETENTION_DAYS=30

echo "Iniciando backup do MySQL..."
mysqldump -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASSWORD \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  $DB_NAME > $BACKUP_FILE

if [ $? -eq 0 ]; then
    echo "Backup criado com sucesso: $BACKUP_FILE"
    
    # Comprimir backup
    gzip $BACKUP_FILE
    echo "Backup comprimido: $BACKUP_FILE.gz"
    
    # Calcular tamanho do backup
    BACKUP_SIZE=$(du -h "$BACKUP_FILE.gz" | cut -f1)
    echo "Tamanho do backup: $BACKUP_SIZE"
    
    # Remover backups antigos
    find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
    echo "Backups antigos removidos (mais de $RETENTION_DAYS dias)"
    
    # Log do backup
    echo "$(date): Backup MySQL criado - $BACKUP_FILE.gz ($BACKUP_SIZE)" >> /var/log/n8n/backup.log
else
    echo "ERRO: Falha no backup do MySQL"
    exit 1
fi

Backup de Workflows

Script de Backup de Workflows

#!/bin/bash

# Configurações
N8N_URL="https://seudominio.com"
API_KEY="sua_api_key"
BACKUP_DIR="/backups/n8n/workflows"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/workflows_$DATE.json"
RETENTION_DAYS=30

echo "Iniciando backup de workflows..."
curl -H "X-N8N-API-KEY: $API_KEY" \
  "$N8N_URL/api/v1/workflows" \
  | jq '.' > $BACKUP_FILE

if [ $? -eq 0 ]; then
    echo "Backup de workflows criado: $BACKUP_FILE"
    
    # Comprimir backup
    gzip $BACKUP_FILE
    echo "Backup comprimido: $BACKUP_FILE.gz"
    
    # Calcular tamanho do backup
    BACKUP_SIZE=$(du -h "$BACKUP_FILE.gz" | cut -f1)
    echo "Tamanho do backup: $BACKUP_SIZE"
    
    # Remover backups antigos
    find $BACKUP_DIR -name "*.json.gz" -mtime +$RETENTION_DAYS -delete
    echo "Backups antigos removidos (mais de $RETENTION_DAYS dias)"
    
    # Log do backup
    echo "$(date): Backup de workflows criado - $BACKUP_FILE.gz ($BACKUP_SIZE)" >> /var/log/n8n/backup.log
else
    echo "ERRO: Falha no backup de workflows"
    exit 1
fi

Script de Backup de Credenciais

#!/bin/bash

# Configurações
N8N_URL="https://seudominio.com"
API_KEY="sua_api_key"
BACKUP_DIR="/backups/n8n/credentials"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/credentials_$DATE.json"
RETENTION_DAYS=30

echo "Iniciando backup de credenciais..."
curl -H "X-N8N-API-KEY: $API_KEY" \
  "$N8N_URL/api/v1/credentials" \
  | jq '.' > $BACKUP_FILE

if [ $? -eq 0 ]; then
    echo "Backup de credenciais criado: $BACKUP_FILE"
    
    # Comprimir backup
    gzip $BACKUP_FILE
    echo "Backup comprimido: $BACKUP_FILE.gz"
    
    # Calcular tamanho do backup
    BACKUP_SIZE=$(du -h "$BACKUP_FILE.gz" | cut -f1)
    echo "Tamanho do backup: $BACKUP_SIZE"
    
    # Remover backups antigos
    find $BACKUP_DIR -name "*.json.gz" -mtime +$RETENTION_DAYS -delete
    echo "Backups antigos removidos (mais de $RETENTION_DAYS dias)"
    
    # Log do backup
    echo "$(date): Backup de credenciais criado - $BACKUP_FILE.gz ($BACKUP_SIZE)" >> /var/log/n8n/backup.log
else
    echo "ERRO: Falha no backup de credenciais"
    exit 1
fi

Backup de Volumes Docker

#!/bin/bash

# Configurações
VOLUME_NAME="n8n_data"
BACKUP_DIR="/backups/n8n/volumes"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/n8n_volume_$DATE.tar.gz"
RETENTION_DAYS=30

echo "Parando container n8n..."
docker stop n8n

echo "Iniciando backup do volume Docker..."
docker run --rm -v $VOLUME_NAME:/data -v $BACKUP_DIR:/backup \
  alpine tar czf /backup/n8n_volume_$DATE.tar.gz -C /data .

echo "Reiniciando container n8n..."
docker start n8n

if [ $? -eq 0 ]; then
    echo "Backup do volume criado: $BACKUP_FILE"
    
    # Calcular tamanho do backup
    BACKUP_SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
    echo "Tamanho do backup: $BACKUP_SIZE"
    
    # Remover backups antigos
    find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
    echo "Backups antigos removidos (mais de $RETENTION_DAYS dias)"
    
    # Log do backup
    echo "$(date): Backup de volume criado - $BACKUP_FILE ($BACKUP_SIZE)" >> /var/log/n8n/backup.log
else
    echo "ERRO: Falha no backup do volume"
    exit 1
fi

Backup na Nuvem

AWS S3

#!/bin/bash

# Configurações
S3_BUCKET="n8n-backups"
S3_REGION="us-east-1"
BACKUP_DIR="/backups/n8n"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=90

echo "Iniciando backup para S3..."

# Backup de banco de dados
aws s3 cp $BACKUP_DIR/database/ s3://$S3_BUCKET/database/ --recursive

# Backup de workflows
aws s3 cp $BACKUP_DIR/workflows/ s3://$S3_BUCKET/workflows/ --recursive

# Backup de credenciais
aws s3 cp $BACKUP_DIR/credentials/ s3://$S3_BUCKET/credentials/ --recursive

# Configurar lifecycle para remoção automática
aws s3api put-bucket-lifecycle-configuration \
  --bucket $S3_BUCKET \
  --lifecycle-configuration '{
    "Rules": [
      {
        "ID": "DeleteOldBackups",
        "Status": "Enabled",
        "Filter": {
          "Prefix": ""
        },
        "Expiration": {
          "Days": '$RETENTION_DAYS'
        }
      }
    ]
  }'

echo "Backup para S3 concluído"

Google Cloud Storage

#!/bin/bash

# Configurações
GCS_BUCKET="n8n-backups"
BACKUP_DIR="/backups/n8n"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=90

echo "Iniciando backup para Google Cloud Storage..."

# Backup de banco de dados
gsutil -m cp $BACKUP_DIR/database/* gs://$GCS_BUCKET/database/

# Backup de workflows
gsutil -m cp $BACKUP_DIR/workflows/* gs://$GCS_BUCKET/workflows/

# Backup de credenciais
gsutil -m cp $BACKUP_DIR/credentials/* gs://$GCS_BUCKET/credentials/

# Configurar lifecycle para remoção automática
gsutil lifecycle set lifecycle.json gs://$GCS_BUCKET

echo "Backup para GCS concluído"

Restauração

Restauração de Banco de Dados

#!/bin/bash

# Configurações
DB_HOST="localhost"
DB_PORT="5432"
DB_NAME="n8n"
DB_USER="n8n"
BACKUP_FILE="$1"

if [ -z "$BACKUP_FILE" ]; then
    echo "Uso: $0 <arquivo_backup>"
    exit 1
fi

# Verificar se arquivo existe
if [ ! -f "$BACKUP_FILE" ]; then
    echo "ERRO: Arquivo de backup não encontrado: $BACKUP_FILE"
    exit 1
fi

echo "Iniciando restauração do PostgreSQL..."

# Parar n8n
echo "Parando n8n..."
docker stop n8n

# Criar backup de segurança
echo "Criando backup de segurança..."
pg_dump -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME > \
  /backups/n8n/pre_restore_backup_$(date +%Y%m%d_%H%M%S).sql

# Descomprimir se necessário
if [[ "$BACKUP_FILE" == *.gz ]]; then
    echo "Descomprimindo backup..."
    gunzip -c "$BACKUP_FILE" > "${BACKUP_FILE%.gz}"
    BACKUP_FILE="${BACKUP_FILE%.gz}"
fi

# Restaurar backup
echo "Restaurando backup..."
psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME < "$BACKUP_FILE"

if [ $? -eq 0 ]; then
    echo "Restauração concluída com sucesso"
    
    # Reiniciar n8n
    echo "Reiniciando n8n..."
    docker start n8n
    
    # Log da restauração
    echo "$(date): Restauração PostgreSQL concluída - $BACKUP_FILE" >> /var/log/n8n/restore.log
else
    echo "ERRO: Falha na restauração"
    exit 1
fi

Restauração de Workflows

#!/bin/bash

# Configurações
N8N_URL="https://seudominio.com"
API_KEY="sua_api_key"
BACKUP_FILE="$1"

if [ -z "$BACKUP_FILE" ]; then
    echo "Uso: $0 <arquivo_backup>"
    exit 1
fi

# Verificar se arquivo existe
if [ ! -f "$BACKUP_FILE" ]; then
    echo "ERRO: Arquivo de backup não encontrado: $BACKUP_FILE"
    exit 1
fi

echo "Iniciando restauração de workflows..."

# Descomprimir se necessário
if [[ "$BACKUP_FILE" == *.gz ]]; then
    echo "Descomprimindo backup..."
    gunzip -c "$BACKUP_FILE" > "${BACKUP_FILE%.gz}"
    BACKUP_FILE="${BACKUP_FILE%.gz}"
fi

# Restaurar workflows
echo "Restaurando workflows..."
jq -c '.[]' "$BACKUP_FILE" | while read workflow; do
    curl -X POST \
      -H "X-N8N-API-KEY: $API_KEY" \
      -H "Content-Type: application/json" \
      -d "$workflow" \
      "$N8N_URL/api/v1/workflows"
    
    if [ $? -eq 0 ]; then
        echo "Workflow restaurado com sucesso"
    else
        echo "ERRO: Falha na restauração do workflow"
    fi
done

echo "Restauração de workflows concluída"

# Log da restauração
echo "$(date): Restauração de workflows concluída - $BACKUP_FILE" >> /var/log/n8n/restore.log

Disaster Recovery

Cenários de Desastre

#!/bin/bash

# Cenários comuns de desastre
DISASTER_SCENARIOS=(
    "Perda de servidor principal"
    "Corrupção de banco de dados"
    "Falha de storage"
    "Desastre natural"
    "Ataque cibernético"
    "Erro humano"
)

Script de Disaster Recovery

#!/bin/bash

# Configurações
PRIMARY_SERVER="n8n.empresa.com"
BACKUP_SERVER="n8n-backup.empresa.com"
S3_BUCKET="n8n-backups"
LATEST_BACKUP=$(aws s3 ls s3://$S3_BUCKET/database/ | sort | tail -1 | awk '{print $4}')

echo "Iniciando Disaster Recovery..."

# 1. Verificar conectividade
echo "Verificando conectividade..."
if ! ping -c 3 $PRIMARY_SERVER > /dev/null; then
    echo "Servidor primário indisponível, iniciando DR..."
    
    # 2. Provisionar servidor de backup
    echo "Provisionando servidor de backup..."
    # Aqui você incluiria comandos para provisionar infraestrutura
    
    # 3. Restaurar banco de dados
    echo "Restaurando banco de dados..."
    aws s3 cp s3://$S3_BUCKET/database/$LATEST_BACKUP /tmp/
    gunzip /tmp/$LATEST_BACKUP
    psql -h localhost -U n8n -d n8n < /tmp/${LATEST_BACKUP%.gz}
    
    # 4. Restaurar workflows
    echo "Restaurando workflows..."
    aws s3 cp s3://$S3_BUCKET/workflows/ /tmp/workflows/ --recursive
    
    # 5. Configurar DNS
    echo "Atualizando DNS..."
    # Comandos para atualizar DNS
    
    # 6. Verificar funcionalidade
    echo "Verificando funcionalidade..."
    curl -f https://$BACKUP_SERVER/healthz
    
    if [ $? -eq 0 ]; then
        echo "Disaster Recovery concluído com sucesso"
        # Notificar equipe
        curl -X POST $WEBHOOK_URL \
          -H "Content-type: application/json" \
          -d '{"text":"✅ Disaster Recovery concluído - n8n disponível em backup"}'
    else
        echo "ERRO: Falha no Disaster Recovery"
        exit 1
    fi
else
    echo "Servidor primário está funcionando"
fi

Testes de Restauração

Script de Teste

#!/bin/bash

# Configurações
BACKUP_FILE="$1"
TEST_DB="n8n_test"

if [ -z "$BACKUP_FILE" ]; then
    echo "Uso: $0 <arquivo_backup>"
    exit 1
fi

echo "Iniciando teste de restauração..."

# Criar ambiente de teste
echo "Criando ambiente de teste..."
docker run -d --name $TEST_ENV \
  -e DB_TYPE=postgresdb \
  -e DB_POSTGRESDB_HOST=localhost \
  -e DB_POSTGRESDB_DATABASE=$TEST_DB \
  -p 5679:5678 \
  n8nio/n8n:latest

# Aguardar inicialização
echo "Aguardando inicialização..."
sleep 30

# Restaurar backup de teste
echo "Restaurando backup de teste..."
gunzip -c "$BACKUP_FILE" | psql -h localhost -U n8n -d $TEST_DB

# Verificar restauração
echo "Verificando restauração..."
WORKFLOW_COUNT=$(curl -s http://localhost:5679/api/v1/workflows | jq '. | length')
echo "Workflows restaurados: $WORKFLOW_COUNT"

# Testar funcionalidade
echo "Testando funcionalidade..."
curl -f http://localhost:5679/healthz

if [ $? -eq 0 ]; then
    echo "✅ Teste de restauração PASSOU"
    # Limpar ambiente de teste
    docker stop $TEST_ENV
    docker rm $TEST_ENV
    psql -h localhost -U n8n -c "DROP DATABASE $TEST_DB;"
else
    echo "❌ Teste de restauração FALHOU"
    exit 1
fi

Limpeza Automática

#!/bin/bash

# Configurações
BACKUP_DIR="/backups/n8n"
RETENTION_DAYS=30
CLOUD_RETENTION_DAYS=90

echo "Iniciando limpeza de backups antigos..."

# Limpar backups locais
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR -name "*.json.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete

# Limpar backups na nuvem
aws s3 ls s3://n8n-backups/ | \
  awk '$1 < "'$(date -d "$CLOUD_RETENTION_DAYS days ago" +%Y-%m-%d)'" {print $4}' | \
  xargs -I {} aws s3 rm s3://n8n-backups/{}

echo "Limpeza concluída"

Checklist de Backup

Configuração

  • Estratégia 3-2-1 implementada
  • Scripts de backup criados
  • Automação com cron configurada
  • Backup na nuvem configurado
  • Retenção de backups definida

Recuperação

  • Scripts de restauração criados
  • Testes de restauração realizados
  • Plano de DR documentado
  • RTO e RPO definidos
  • Procedimentos de recuperação testados

Monitoramento

  • Logs de backup configurados
  • Alertas de falha configurados
  • Métricas de backup coletadas
  • Relatórios de backup gerados
  • Verificação de integridade implementada

Documentação

  • Procedimentos documentados
  • Contatos de emergência definidos
  • Matriz de responsabilidades
  • Plano de comunicação
  • Exercícios de DR realizados

Próximos Passos

  1. Configure automação de backups
  2. Teste restaurações regularmente
  3. Monitore integridade dos backups
  4. Documente procedimentos de DR

Dica Pro

Teste restaurações regularmente em ambiente isolado para garantir que seus backups são funcionais.

Importante

Mantenha múltiplas cópias de backup em locais diferentes e teste procedimentos de restauração antes de precisar deles.