Backup criptografado e offsite da VPS

    Backup não é opcional — é quando (não se) você vai precisar, seja por falha de hardware, ransomware, erro humano ou comprometimento do servidor. A regra 3-2-1: 3 cópias dos dados, 2 mídias diferentes, 1 cópia offsite. Na VPS, isso significa backup local + envio automático para object storage externo (S3, R2, ou similar) com criptografia.

    Restic: backup incremental e criptografado

    Restic é a melhor ferramenta para backup de arquivos de VPS — incremental, criptografado por padrão, deduplicado e suporta múltiplos destinos:

    bash
    # Instalar restic
    apt install restic
    # ou versão mais recente:
    wget https://github.com/restic/restic/releases/latest/download/restic_linux_amd64.bz2
    bunzip2 restic_linux_amd64.bz2 && mv restic_linux_amd64 /usr/local/bin/restic
    chmod +x /usr/local/bin/restic
    
    # Inicializar repositório de backup (com senha forte)
    export RESTIC_PASSWORD="sua_senha_forte_aqui"
    restic init --repo /opt/backup/local
    
    # Para backup no S3/Cloudflare R2:
    export AWS_ACCESS_KEY_ID="sua_access_key"
    export AWS_SECRET_ACCESS_KEY="seu_secret_key"
    restic init --repo s3:https://SEU_ENDPOINT_R2/nome-do-bucket/vps-backups
    
    # Primeiro backup (backup completo)
    restic backup /opt/app /etc /home --repo /opt/backup/local
    
    # Backups subsequentes são automáticos e incrementais
    restic snapshots --repo /opt/backup/local
    Dica
    Restic usa criptografia AES-256 por padrão — os dados no S3/R2 são ilegíveis sem a senha. Guarde a senha em local seguro (gerenciador de senhas ou impressa). Sem a senha, os backups são irrecuperáveis.

    Backup automático do PostgreSQL

    Backup do banco separado dos arquivos — deve ser feito com pg_dump para consistência:

    bash
    #!/bin/bash
    # /opt/scripts/backup-postgres.sh
    
    set -euo pipefail
    
    DB_NAME="meu_banco"
    DB_USER="postgres"
    BACKUP_DIR="/opt/backup/postgres"
    DATE=$(date +%Y-%m-%d_%H-%M-%S)
    BACKUP_FILE="$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz"
    
    mkdir -p "$BACKUP_DIR"
    
    # Dump comprimido
    docker compose -f /opt/app/docker-compose.yml exec -T postgres \
      pg_dump -U "$DB_USER" "$DB_NAME" | gzip > "$BACKUP_FILE"
    
    echo "Backup criado: $BACKUP_FILE ($(du -sh $BACKUP_FILE | cut -f1))"
    
    # Enviar para S3/R2 com restic
    export RESTIC_PASSWORD="$RESTIC_PASSWORD"
    restic backup "$BACKUP_FILE" --repo s3:https://SEU_ENDPOINT/backups-db
    
    # Manter apenas os últimos 7 backups locais
    find "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 -delete
    
    echo "Backup concluído: $BACKUP_FILE"

    Política de retenção com restic

    Defina por quanto tempo manter snapshots antigos para balancear espaço e cobertura:

    bash
    # Política de retenção: 7 diários, 4 semanais, 6 mensais
    restic forget \
      --repo s3:https://SEU_ENDPOINT/backups \
      --keep-daily 7 \
      --keep-weekly 4 \
      --keep-monthly 6 \
      --prune
    
    # Ver snapshots disponíveis
    restic snapshots --repo s3:https://SEU_ENDPOINT/backups
    
    # Verificar integridade do repositório (importante!)
    restic check --repo s3:https://SEU_ENDPOINT/backups
    
    # Cron para backup diário às 2h e forget semanal
    # /etc/cron.d/restic-backup
    # 0 2 * * * root /opt/scripts/backup-daily.sh
    # 0 3 * * 0 root restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune --repo ...
    Dica
    restic check verifica que os dados no repositório não estão corrompidos. Execute semanalmente — um backup corrompido que só se descobre no momento da restauração é tão útil quanto nenhum backup.

    Testar a restauração (obrigatório)

    Backup não testado não é backup. Teste a restauração periodicamente:

    bash
    # Listar snapshots disponíveis
    restic snapshots --repo s3:https://SEU_ENDPOINT/backups
    
    # Restaurar snapshot específico em diretório temporário
    restic restore SNAPSHOT_ID \
      --repo s3:https://SEU_ENDPOINT/backups \
      --target /tmp/restore-test
    
    # Verificar que os arquivos foram restaurados
    ls -la /tmp/restore-test/opt/app/
    
    # Restaurar apenas arquivos específicos
    restic restore latest \
      --repo s3:https://SEU_ENDPOINT/backups \
      --target /tmp/restore-test \
      --include "/opt/app/.env"
    
    # Para banco: restaurar o dump e importar
    gunzip -c /tmp/restore-test/opt/backup/postgres/db_2026-06-07.sql.gz | \
      docker compose exec -T postgres psql -U postgres meu_banco

    Script completo de backup diário

    Script de backup com notificação por e-mail em caso de falha:

    bash
    #!/bin/bash
    # /opt/scripts/backup-daily.sh
    set -euo pipefail
    
    LOG_FILE="/var/log/backup-daily.log"
    exec >> "$LOG_FILE" 2>&1
    
    echo "=== Backup iniciado: $(date) ==="
    
    # Variáveis de ambiente
    source /opt/scripts/.backup-env
    
    # 1. Backup do banco de dados
    /opt/scripts/backup-postgres.sh
    
    # 2. Backup de arquivos com restic
    restic backup \
      /opt/app \
      /etc/nginx \
      /etc/letsencrypt \
      --repo "$RESTIC_REPO" \
      --exclude "node_modules" \
      --exclude ".git" \
      --tag "daily"
    
    # 3. Política de retenção
    restic forget \
      --repo "$RESTIC_REPO" \
      --keep-daily 7 --keep-weekly 4 \
      --prune --quiet
    
    echo "=== Backup concluído: $(date) ==="

    $ 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