Estratégia de backup para VPS

    Backup não é apenas fazer uma cópia — é ter um plano testado para restaurar em tempo hábil quando algo dá errado. Uma VPS em produção precisa de estratégia de backup para banco de dados, arquivos de upload, configurações e certificados. A regra 3-2-1 (3 cópias, 2 mídias, 1 offsite) é o ponto de partida.

    O que fazer backup na VPS

    Mapeie todos os dados que precisam de backup antes de definir a estratégia:

    bash
    # Checklist de o que fazer backup:
    
    # 1. Banco de dados (mais crítico)
    # ├── PostgreSQL: pg_dump de cada banco
    # ├── MySQL/MariaDB: mysqldump
    # ├── Redis: dump.rdb (se persistência habilitada)
    # └── SQLite: cópia do arquivo .db
    
    # 2. Arquivos de upload dos usuários
    # ├── /var/www/uploads/ (imagens, documentos)
    # └── /opt/app/storage/ (arquivos da aplicação)
    
    # 3. Configurações e secrets
    # ├── /etc/nginx/ (config do web server)
    # ├── /etc/letsencrypt/ (certificados SSL)
    # ├── /opt/app/.env (variáveis de ambiente)
    # └── /etc/cron.d/ (crontabs customizados)
    
    # 4. Dados de serviços self-hosted
    # ├── /var/lib/docker/volumes/ (volumes Docker)
    # └── Configurações de apps (Grafana, n8n, etc.)
    
    # O que NÃO precisa de backup:
    # ✗ Código fonte (está no Git)
    # ✗ node_modules, .venv (regeneráveis)
    # ✗ Logs antigos (arquivar separadamente se necessário)
    # ✗ Arquivos temporários e cache

    Script de backup completo da VPS

    Script que faz backup de banco + arquivos + configurações:

    bash
    #!/bin/bash
    # /opt/scripts/backup-full.sh
    set -euo pipefail
    
    BACKUP_DIR="/var/backups/vps"
    DATE=$(date +%Y%m%d_%H%M)
    RETENTION_DAYS=7
    LOG="/var/log/backup-full.log"
    exec >> "$LOG" 2>&1
    
    echo "=== Backup completo: $(date) ==="
    mkdir -p "$BACKUP_DIR"
    
    # 1. Banco de dados PostgreSQL
    echo "--- PostgreSQL ---"
    PGPASSWORD="$DB_PASSWORD" pg_dump -U minha_app minha_db \
      | gzip > "$BACKUP_DIR/postgres_${DATE}.sql.gz"
    
    # 2. Arquivos de upload
    echo "--- Uploads ---"
    tar -czf "$BACKUP_DIR/uploads_${DATE}.tar.gz" \
      --exclude='*.tmp' \
      /var/www/uploads/ 2>/dev/null || true
    
    # 3. Configurações
    echo "--- Configs ---"
    tar -czf "$BACKUP_DIR/configs_${DATE}.tar.gz" \
      /etc/nginx/ \
      /etc/letsencrypt/ \
      /opt/app/.env \
      /etc/cron.d/ 2>/dev/null || true
    
    # 4. Upload para S3 (ou B2/Wasabi)
    echo "--- Upload offsite ---"
    aws s3 sync "$BACKUP_DIR" s3://meu-bucket/vps-backups/ \
      --exclude "*" \
      --include "*_${DATE}*" \
      --storage-class STANDARD_IA
    
    # 5. Limpar backups locais antigos
    find "$BACKUP_DIR" -mtime +$RETENTION_DAYS -delete
    
    echo "=== Backup concluído: $(date) ==="

    Backup incremental com restic

    restic é uma ferramenta moderna de backup com deduplicação, compressão e criptografia:

    bash
    # Instalar restic
    sudo apt install -y restic
    
    # Inicializar repositório (S3 como backend):
    export AWS_ACCESS_KEY_ID="sua_key"
    export AWS_SECRET_ACCESS_KEY="sua_secret"
    export RESTIC_REPOSITORY="s3:sa-east-1.amazonaws.com/meu-bucket/restic"
    export RESTIC_PASSWORD="senha_de_criptografia_forte"
    
    restic init
    
    # Fazer backup de múltiplos diretórios:
    restic backup \
      /var/www \
      /opt/app \
      /etc/nginx \
      /etc/letsencrypt \
      --exclude "/var/www/cache" \
      --exclude "*.log" \
      --tag "vps-producao"
    
    # Listar snapshots:
    restic snapshots
    
    # Verificar integridade:
    restic check
    
    # Política de retenção automática:
    restic forget \
      --keep-daily 7 \
      --keep-weekly 4 \
      --keep-monthly 12 \
      --prune
    
    # Vantagens do restic:
    # + Deduplicação: backup incremental real (apenas blocos novos)
    # + Criptografia: AES-256 antes de enviar para o cloud
    # + Verificação: hash de integridade de cada bloco

    Definir RTO e RPO para cada componente

    Recovery Time Objective e Recovery Point Objective guiam a estratégia:

    bash
    # RTO: quanto tempo tenho para restaurar?
    # RPO: quanta perda de dados é aceitável?
    
    # Exemplo de tabela de SLA para VPS de API:
    #
    # Componente          | RPO         | RTO    | Estratégia
    # ─────────────────────────────────────────────────────────
    # Banco PostgreSQL    | 1 hora      | 2 horas | pg_dump a cada hora + offsite
    # Arquivos de upload  | 24 horas    | 4 horas | backup diário + S3
    # Certificados SSL    | 7 dias      | 30 min  | Let's Encrypt auto-renova
    # Configurações       | 7 dias      | 1 hora  | backup semanal + Git
    # Código da aplicação | 0 (em Git)  | 30 min  | git clone + deploy
    
    # Calcular custo de armazenamento:
    # 10 GB de dados, backup diário por 30 dias:
    # Sem dedup: 300 GB × $0.023/GB (S3 Standard) = $6.90/mês
    # Com restic (dedup ~70%): ~90 GB × $0.0125/GB (S3 IA) = $1.13/mês

    Rotina de teste de restore

    Agende testes periódicos para confirmar que o backup está funcional:

    bash
    #!/bin/bash
    # /opt/scripts/test-restore-weekly.sh
    # Agendar: todo domingo às 5h
    # 0 5 * * 0 /opt/scripts/test-restore-weekly.sh
    
    set -euo pipefail
    LOG="/var/log/restore-test.log"
    exec >> "$LOG" 2>&1
    
    echo "=== Teste de restore semanal: $(date) ==="
    
    # 1. Baixar backup mais recente do S3
    LATEST=$(aws s3 ls s3://meu-bucket/vps-backups/ \
      --recursive | grep postgres | sort | tail -1 | awk '{print $4}')
    aws s3 cp "s3://meu-bucket/$LATEST" /tmp/test-backup.sql.gz
    
    # 2. Testar restore do PostgreSQL
    TEST_DB="restore_test_$(date +%s)"
    sudo -u postgres createdb "$TEST_DB"
    gunzip -c /tmp/test-backup.sql.gz | sudo -u postgres psql "$TEST_DB" > /dev/null
    
    # 3. Validar integridade
    ROWS=$(sudo -u postgres psql -d "$TEST_DB" -t -c "SELECT count(*) FROM usuarios")
    echo "Linhas na tabela usuarios: $ROWS"
    [ "$ROWS" -gt 0 ] || (echo "FALHA: tabela vazia!" && exit 1)
    
    # 4. Limpar
    sudo -u postgres dropdb "$TEST_DB"
    rm /tmp/test-backup.sql.gz
    
    echo "=== Teste concluído com sucesso: $(date) ==="
    Dica
    Teste de restore automatizado sem output de erro = backup funcionando. Configure alertas para te notificar quando o script falhar — é seu sinal de que algo quebrou na pipeline de backup.

    $ runstack deploy --plan starter

    Não quer configurar manualmente?

    Não quer configurar manualmente? Implante o VPS em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.

    Perguntas frequentes