{ "name": "💾 Backup Automático | Sistema Completo", "nodes": [ { "parameters": { "rule": { "interval": [ { "field": "cronExpression", "expression": "0 2 * * *" } ] } }, "id": "cron-daily-backup", "name": "Trigger Diário (2h)", "type": "n8n-nodes-base.cron", "typeVersion": 1, "position": [240, 300] }, { "parameters": { "jsCode": "// Configurações de backup\nconst backupConfig = {\n timestamp: new Date().toISOString().replace(/[:.]/g, '-').substring(0, 19),\n date: new Date().toLocaleDateString('pt-BR'),\n time: new Date().toLocaleTimeString('pt-BR'),\n backupDir: `/backup/${new Date().toISOString().split('T')[0]}`,\n retention_days: 30, // Manter backups por 30 dias\n services: [\n 'bookstack',\n 'krayin-crm', \n 'n8n',\n 'evolution-api'\n ]\n};\n\n// Lista de bases de dados para backup\nconst databases = [\n {\n name: 'bookstackapp',\n container: 'bookstack_bookstack_db',\n user: 'bookstack',\n password: 'bookstack_secure_2026'\n },\n {\n name: 'krayin',\n container: 'krayin_mysql',\n user: 'krayin',\n password: 'krayin_db_pass_2026'\n }\n];\n\n// Lista de volumes Docker para backup\nconst volumes = [\n 'bookstack_app',\n 'bookstack_db',\n 'krayin_app_data',\n 'evolution_data',\n 'n8n_data'\n];\n\nreturn {\n config: backupConfig,\n databases: databases,\n volumes: volumes,\n backupFilename: `backup-completo-${backupConfig.timestamp}`\n};" }, "id": "prepare-backup", "name": "Preparar Configuração", "type": "n8n-nodes-base.code", "typeVersion": 1, "position": [460, 300] }, { "parameters": { "command": "mkdir -p {{$node[\"Preparar Configuração\"].json[\"config\"][\"backupDir\"]}}" }, "id": "create-backup-dir", "name": "Criar Diretório", "type": "n8n-nodes-base.executeCommand", "typeVersion": 1, "position": [680, 300] }, { "parameters": { "command": "#!/bin/bash\n\n# Configurações do backup\nBACKUP_DIR=\"{{$node[\"Preparar Configuração\"].json[\"config\"][\"backupDir\"]}}\"\nTIMESTAMP=\"{{$node[\"Preparar Configuração\"].json[\"config\"][\"timestamp\"]}}\"\n\necho \"🚀 Iniciando backup automático - $TIMESTAMP\"\n\n# 1. BACKUP DE BASES DE DADOS\necho \"📊 Fazendo backup das bases de dados...\"\n\n# BookStack Database\ndocker exec bookstack_bookstack_db.1.$(docker service ps -q bookstack_bookstack_db | head -n1) \\\n mariadb-dump -u bookstack -pbookstack_secure_2026 --single-transaction bookstackapp \\\n > \"$BACKUP_DIR/bookstack_database_$TIMESTAMP.sql\"\n\nif [ $? -eq 0 ]; then\n echo \"✅ BookStack database backup concluído\"\nelse\n echo \"❌ Erro no backup do BookStack database\"\nfi\n\n# Compactar SQL\ngzip \"$BACKUP_DIR/bookstack_database_$TIMESTAMP.sql\"\n\n# 2. BACKUP DE VOLUMES DOCKER\necho \"📦 Fazendo backup dos volumes...\"\n\n# Lista de volumes para backup\nVOLUMES=(\"bookstack_app\" \"bookstack_db\" \"n8n_data\")\n\nfor volume in \"${VOLUMES[@]}\"; do\n echo \"📁 Backup do volume: $volume\"\n \n docker run --rm \\\n -v \"$volume:/source:ro\" \\\n -v \"/backup:/backup\" \\\n alpine:latest \\\n tar -czf \"/backup/$(basename $BACKUP_DIR)/${volume}_$TIMESTAMP.tar.gz\" -C /source .\n \n if [ $? -eq 0 ]; then\n echo \"✅ Volume $volume backup concluído\"\n else\n echo \"❌ Erro no backup do volume $volume\"\n fi\ndone\n\n# 3. BACKUP DE CONFIGURAÇÕES\necho \"⚙️ Fazendo backup das configurações...\"\n\n# Docker Compose files\ncp /home/*/docker-compose.yml \"$BACKUP_DIR/docker-compose_$TIMESTAMP.yml\" 2>/dev/null || echo \"⚠️ docker-compose.yml não encontrado\"\ncp /home/*/*.yml \"$BACKUP_DIR/\" 2>/dev/null || echo \"⚠️ Arquivos yml adicionais não encontrados\"\n\n# Scripts e configurações\ncp -r /home/*/scripts \"$BACKUP_DIR/scripts_$TIMESTAMP\" 2>/dev/null || echo \"⚠️ Diretório scripts não encontrado\"\n\n# 4. INFORMAÇÕES DO SISTEMA\necho \"💻 Coletando informações do sistema...\"\n\n# Status dos serviços\ndocker service ls > \"$BACKUP_DIR/docker_services_$TIMESTAMP.txt\"\ndocker ps > \"$BACKUP_DIR/docker_containers_$TIMESTAMP.txt\"\ndocker volume ls > \"$BACKUP_DIR/docker_volumes_$TIMESTAMP.txt\"\n\n# Uso de disco\ndf -h > \"$BACKUP_DIR/disk_usage_$TIMESTAMP.txt\"\n\n# Informações do sistema\nuname -a > \"$BACKUP_DIR/system_info_$TIMESTAMP.txt\"\nfree -h >> \"$BACKUP_DIR/system_info_$TIMESTAMP.txt\"\n\n# 5. LIMPEZA DE BACKUPS ANTIGOS\necho \"🧹 Limpando backups antigos...\"\nfind /backup -type f -mtime +{{$node[\"Preparar Configuração\"].json[\"config\"][\"retention_days\"]}} -delete\nfind /backup -type d -empty -delete\n\n# 6. RELATÓRIO FINAL\necho \"📋 Gerando relatório do backup...\"\n\n# Calcular tamanho total do backup\nTOTAL_SIZE=$(du -sh \"$BACKUP_DIR\" | cut -f1)\n\n# Criar relatório\ncat > \"$BACKUP_DIR/backup_report_$TIMESTAMP.txt\" << EOF\n🎯 RELATÓRIO DE BACKUP AUTOMÁTICO\n========================================\nData/Hora: $(date '+%d/%m/%Y %H:%M:%S')\nTimestamp: $TIMESTAMP\nDiretório: $BACKUP_DIR\nTamanho Total: $TOTAL_SIZE\n\n📊 ARQUIVOS GERADOS:\n$(ls -la $BACKUP_DIR)\n\n💻 STATUS DOS SERVIÇOS:\n$(docker service ls)\n\n📦 VOLUMES DOCKER:\n$(docker volume ls)\n\n💾 ESPAÇO EM DISCO:\n$(df -h)\n\n✅ BACKUP CONCLUÍDO COM SUCESSO!\nEOF\n\necho \"✅ Backup automático concluído!\"\necho \"📁 Localização: $BACKUP_DIR\"\necho \"📊 Tamanho: $TOTAL_SIZE\"" }, "id": "execute-backup", "name": "Executar Backup", "type": "n8n-nodes-base.executeCommand", "typeVersion": 1, "position": [900, 300] }, { "parameters": { "jsCode": "// Processar resultado do backup\nconst backupOutput = $node[\"Executar Backup\"].json.stdout || '';\nconst backupError = $node[\"Executar Backup\"].json.stderr || '';\n\n// Extrair informações do output\nconst isSuccessful = backupOutput.includes('✅ Backup automático concluído!');\nconst backupDir = $node[\"Preparar Configuração\"].json.config.backupDir;\n\n// Contar arquivos gerados (estimativa baseada no output)\nconst fileCount = (backupOutput.match(/✅/g) || []).length;\n\n// Extrair tamanho se disponível\nconst sizeMatch = backupOutput.match(/Tamanho: ([\\d.,]+[KMGT]?B)/i);\nconst totalSize = sizeMatch ? sizeMatch[1] : 'Não determinado';\n\nconst summary = {\n success: isSuccessful,\n timestamp: $node[\"Preparar Configuração\"].json.config.timestamp,\n date: $node[\"Preparar Configuração\"].json.config.date,\n time: $node[\"Preparar Configuração\"].json.config.time,\n backup_directory: backupDir,\n estimated_files: fileCount,\n total_size: totalSize,\n duration: 'Calculado após execução',\n status_emoji: isSuccessful ? '✅' : '❌',\n status_text: isSuccessful ? 'SUCESSO' : 'FALHA',\n has_errors: backupError.length > 0,\n error_details: backupError.substring(0, 500) // Primeiros 500 chars de erro\n};\n\nreturn summary;" }, "id": "process-backup-result", "name": "Processar Resultado", "type": "n8n-nodes-base.code", "typeVersion": 1, "position": [1120, 300] }, { "parameters": { "conditions": { "boolean": [ { "value1": "={{$node[\"Processar Resultado\"].json[\"success\"]}}", "value2": true } ] } }, "id": "check-backup-success", "name": "Backup Sucesso?", "type": "n8n-nodes-base.if", "typeVersion": 1, "position": [1340, 300] }, { "parameters": { "channel": "#tech-alerts", "text": "{{$node[\"Processar Resultado\"].json[\"status_emoji\"]}} **BACKUP AUTOMÁTICO** - {{$node[\"Processar Resultado\"].json[\"status_text\"]}}", "attachments": [ { "color": "{{$node[\"Processar Resultado\"].json[\"success\"] ? '#28a745' : '#dc3545'}}", "fields": [ { "title": "📅 Data/Hora", "value": "{{$node[\"Processar Resultado\"].json[\"date\"]}} às {{$node[\"Processar Resultado\"].json[\"time\"]}}", "short": true }, { "title": "📁 Diretório", "value": "`{{$node[\"Processar Resultado\"].json[\"backup_directory\"]}}`", "short": true }, { "title": "📊 Arquivos Gerados", "value": "{{$node[\"Processar Resultado\"].json[\"estimated_files\"]}} arquivos", "short": true }, { "title": "💾 Tamanho Total", "value": "{{$node[\"Processar Resultado\"].json[\"total_size\"]}}", "short": true }, { "title": "🎯 Componentes", "value": "• BookStack Database\\n• Volumes Docker\\n• Configurações\\n• Info Sistema", "short": false } ],\n \"footer\": \"Sistema de Backup MeMude Core\",\n \"ts\": \"{{Math.floor(Date.now() / 1000)}}\"\n }\n ],\n \"otherOptions\": {\n \"username\": \"Backup Bot\",\n \"icon_emoji\": \":floppy_disk:\"\n }\n },\n \"id\": \"notify-success\",\n \"name\": \"Notificar Sucesso\",\n \"type\": \"n8n-nodes-base.slack\",\n \"typeVersion\": 1,\n \"position\": [1560, 200],\n \"credentials\": {\n \"slackApi\": {\n \"id\": \"slack-memude-workspace\",\n \"name\": \"Slack MeMude Workspace\"\n }\n }\n },\n {\n \"parameters\": {\n \"channel\": \"#tech-alerts\",\n \"text\": \"🚨 **FALHA NO BACKUP AUTOMÁTICO** ❌\",\n \"attachments\": [\n {\n \"color\": \"#dc3545\",\n \"title\": \"⚠️ ATENÇÃO IMEDIATA NECESSÁRIA\",\n \"fields\": [\n {\n \"title\": \"📅 Tentativa\",\n \"value\": \"{{$node[\"Processar Resultado\"].json[\"date\"]}} às {{$node[\"Processar Resultado\"].json[\"time\"]}}\",\n \"short\": true\n },\n {\n \"title\": \"❌ Erros Detectados\",\n \"value\": \"{{$node[\"Processar Resultado\"].json[\"has_errors\"] ? 'SIM' : 'NÃO'}}\",\n \"short\": true\n },\n {\n \"title\": \"🔍 Detalhes do Erro\",\n \"value\": \"`{{$node[\"Processar Resultado\"].json[\"error_details\"] || 'Verificar logs do sistema'}}`\",\n \"short\": false\n }\n ],\n \"actions\": [\n {\n \"type\": \"button\",\n \"text\": \"🔧 Verificar Sistema\",\n \"style\": \"danger\",\n \"url\": \"https://docs.memudecore.com.br\"\n }\n ],\n \"footer\": \"🚨 Sistema de Backup - FALHA\",\n \"ts\": \"{{Math.floor(Date.now() / 1000)}}\"\n }\n ],\n \"otherOptions\": {\n \"username\": \"🚨 BACKUP ALERT\",\n \"icon_emoji\": \":warning:\"\n }\n },\n \"id\": \"notify-failure\",\n \"name\": \"Notificar Falha\",\n \"type\": \"n8n-nodes-base.slack\",\n \"typeVersion\": 1,\n \"position\": [1560, 400],\n \"credentials\": {\n \"slackApi\": {\n \"id\": \"slack-memude-workspace\",\n \"name\": \"Slack MeMude Workspace\"\n }\n }\n }\n ],\n \"connections\": {\n \"Trigger Diário (2h)\": {\n \"main\": [\n [\n {\n \"node\": \"Preparar Configuração\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Preparar Configuração\": {\n \"main\": [\n [\n {\n \"node\": \"Criar Diretório\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Criar Diretório\": {\n \"main\": [\n [\n {\n \"node\": \"Executar Backup\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Executar Backup\": {\n \"main\": [\n [\n {\n \"node\": \"Processar Resultado\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Processar Resultado\": {\n \"main\": [\n [\n {\n \"node\": \"Backup Sucesso?\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Backup Sucesso?\": {\n \"main\": [\n [\n {\n \"node\": \"Notificar Sucesso\",\n \"type\": \"main\",\n \"index\": 0\n }\n ],\n [\n {\n \"node\": \"Notificar Falha\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": true,\n \"settings\": {\n \"timezone\": \"America/Sao_Paulo\",\n \"saveManualExecutions\": true\n },\n \"createdAt\": \"2026-01-21T19:30:00.000Z\",\n \"updatedAt\": \"2026-01-21T19:30:00.000Z\",\n \"id\": \"backup-automatico-completo\",\n \"tags\": [\n {\n \"id\": \"backup\",\n \"name\": \"Backup\"\n },\n {\n \"id\": \"maintenance\",\n \"name\": \"Manutenção\"\n },\n {\n \"id\": \"automation\",\n \"name\": \"Automação\"\n }\n ]\n}" }, "id": "notify-failure", "name": "Notificar Falha", "type": "n8n-nodes-base.slack", "typeVersion": 1, "position": [1560, 400], "credentials": { "slackApi": { "id": "slack-memude-workspace", "name": "Slack MeMude Workspace" } } } ], "connections": { "Trigger Diário (2h)": { "main": [ [ { "node": "Preparar Configuração", "type": "main", "index": 0 } ] ] }, "Preparar Configuração": { "main": [ [ { "node": "Criar Diretório", "type": "main", "index": 0 } ] ] }, "Criar Diretório": { "main": [ [ { "node": "Executar Backup", "type": "main", "index": 0 } ] ] }, "Executar Backup": { "main": [ [ { "node": "Processar Resultado", "type": "main", "index": 0 } ] ] }, "Processar Resultado": { "main": [ [ { "node": "Backup Sucesso?", "type": "main", "index": 0 } ] ] }, "Backup Sucesso?": { "main": [ [ { "node": "Notificar Sucesso", "type": "main", "index": 0 } ], [ { "node": "Notificar Falha", "type": "main", "index": 0 } ] ] } }, "active": true, "settings": { "timezone": "America/Sao_Paulo", "saveManualExecutions": true }, "createdAt": "2026-01-21T19:30:00.000Z", "updatedAt": "2026-01-21T19:30:00.000Z", "id": "backup-automatico-completo", "tags": [ { "id": "backup", "name": "Backup" }, { "id": "maintenance", "name": "Manutenção" }, { "id": "automation", "name": "Automação" } ] }