Tutorial: automatizar snapshots LVM e uploads incrementais para S3 usando systemd timers e Restic no Debian

Hospedagem & VPS · Por · Publicado em · 10 min de leitura

Aeronave estacionada na posição de embarque no pátio do aeroporto sob céu nublado
Metáfora visual para transferência e orquestração de backups automatizados Foto: dmncwndrlch / Pixabay

Este tutorial mostra, passo a passo, como automatizar snapshots LVM e fazer uploads incrementais para S3 com Restic no Debian, orquestrando tudo com systemd timers. Você terá scripts prontos, unidades do systemd e dicas de verificação e recuperação. Requer acesso root e atenção às etapas para evitar interrupções.

Arquitetura do backup: LVM snapshot + Restic + S3

A estratégia combina três peças: snapshot em LVM para congelar um ponto consistente do volume, Restic para realizar o backup incremental e criptografado, e S3 como armazenamento remoto. O systemd agenda e garante execução confiável, com logs centralizados no journal.

Fluxo resumido: criar snapshot LVM (copy-on-write), montar em readonly, executar restic backup no snapshot, desmontar e remover o snapshot. Em janela de manutenção do backup, o sistema segue operando no volume original normalmente.

O Restic armazena apenas blocos alterados entre execuções, reduzindo tráfego e tempo. A retenção é aplicada com forget + prune. Se você usa cron, avaliar migrar para timers melhora observabilidade e robustez.

  • Snapshot LVM: captura ponto no tempo sem parar serviços.
  • Restic: deduplicação, criptografia por padrão, incremental eficiente.
  • S3: armazenamento remoto resiliente.
  • systemd: agendador com logs, retries e dependências.

Pré-requisitos e planejamento de capacidade

Antes de começar, confirme o ambiente e dimensione o snapshot. Operações em LVM incorretas podem causar indisponibilidade ou perda de dados. Teste primeiro em um servidor de homologação.

Para segurança básica do servidor, revise a lista de boas práticas em checklist de segurança para VPS Linux.

  • Debian 11/12 com acesso root.
  • Pacotes: lvm2, restic.
  • Volume LVM (VG/LV) com espaço livre no VG para o snapshot (tamanho depende da taxa de escrita durante o backup).
  • Bucket S3 acessível pela rede e credenciais IAM com permissão restrita.
  • Sincronização de horário (timers dependem de clock correto).
  • Planeje exclusões (caches, tmp, mounts) para evitar ruído no backup.

Bucket S3 e credenciais IAM mínimas

Crie um bucket exclusivo para backups (por projeto/ambiente) e um usuário IAM com acesso restrito apenas a esse bucket. Use chaves de acesso dedicadas. Consulte a documentação do Amazon S3 para criar o bucket e políticas.

O Restic usa a URL do repositório no formato s3:https://endpoint/bucket/prefix. Em S3 padrão: s3:https://s3.amazonaws.com/seu-bucket/prefix. Ajuste a região conforme seu bucket.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ResticBackupAccess",
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:ListBucketVersions"
      ],
      "Resource": [
        "arn:aws:s3:::SEU-BUCKET"
      ]
    },
    {
      "Sid": "ResticObjectsAccess",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:ListBucketMultipartUploads",
        "s3:AbortMultipartUpload"
      ],
      "Resource": [
        "arn:aws:s3:::SEU-BUCKET/*"
      ]
    }
  ]
}

Instalar Restic e configurar variáveis seguras

Instale os pacotes e centralize as credenciais/variáveis do Restic em um arquivo root-only. Proteja esse arquivo (0600). Crie também um arquivo de exclusões para evitar backup de caches/mounts temporários.

Variáveis comuns estão na tabela abaixo. Adapte ao seu ambiente.

Variável Exemplo Descrição
RESTIC_REPOSITORY s3:https://s3.amazonaws.com/meu-bucket/projeto1 URL do repositório Restic em S3
RESTIC_PASSWORD uma-senha-forte Senha de criptografia do repositório
AWS_ACCESS_KEY_ID AKIA... Chave de acesso AWS
AWS_SECRET_ACCESS_KEY xxxxxxxx Chave secreta AWS
AWS_DEFAULT_REGION us-east-1 Região do bucket
BACKUP_TAGS vps-01,lvm-snapshot Tags aplicadas aos snapshots do Restic
set -euo pipefail
apt update && apt install -y lvm2 restic

install -d -m 0700 /etc/restic
cat > /etc/restic.env <<'EOF'
RESTIC_REPOSITORY=s3:https://s3.amazonaws.com/SEU-BUCKET/projeto1
RESTIC_PASSWORD=troque-esta-senha
AWS_ACCESS_KEY_ID=COLOQUE_SUA_CHAVE
AWS_SECRET_ACCESS_KEY=COLOQUE_SUA_SECRETA
AWS_DEFAULT_REGION=us-east-1
BACKUP_TAGS=vps-01,lvm-snapshot
EOF
chmod 0600 /etc/restic.env

# Exclusões do backup (ajuste conforme necessário)
install -d -m 0755 /etc/restic
cat > /etc/restic/excludes.txt <<'EOF'
/proc/*
/sys/*
/run/*
/tmp/*
/var/tmp/*
/var/cache/*
/mnt/*
/media/*
/swapfile
EOF

Inicializar o repositório e validar conexão

Inicialize o repositório no S3 e faça um teste rápido de backup/consulta. Use uma variável de ambiente para carregar as credenciais antes de chamar o Restic. Guarde a senha (RESTIC_PASSWORD): sem ela, você não recupera os dados.

set -euo pipefail
set -a
. /etc/restic.env
set +a

# Inicializa o repositório (executar apenas uma vez)
restic init

# Teste rápido de backup (arquivo pequeno)
restic backup --tag test /etc/hosts --exclude-file=/etc/restic/excludes.txt

# Lista snapshots para confirmar
restic snapshots

Script de backup com snapshot LVM (atômico e com limpeza)

O script abaixo cria um snapshot LVM readonly, monta, executa o backup incremental com Restic e remove o snapshot com limpeza garantida via trap. Inclui um lock simples para evitar concorrência. Ajuste VG/LV, tamanho do snapshot e paths.

Se você faz backup do volume raiz, certifique espaço livre no VG. Para bancos de dados, considere um dump coordenado ou um freeze curto do filesystem para consistência lógica.

#!/usr/bin/env bash
set -euo pipefail

# Configuração específica do host
VG_NAME="vg0"            # Volume Group
LV_NAME="root"           # Logical Volume original
SNAP_SIZE="5G"           # Tamanho do snapshot (depende da taxa de escrita)
MOUNT_POINT="/mnt/backup-snap"
SNAP_NAME="${LV_NAME}-snap-$(date +%Y%m%d%H%M%S)"
LOCK_FILE="/var/lock/restic-lvm-backup.lock"

exec 9>"$LOCK_FILE" || true
if ! flock -n 9; then
  echo "Outro backup está em execução. Abortando." >&2
  exit 1
fi

cleanup() {
  set +e
  if mountpoint -q "$MOUNT_POINT"; then umount "$MOUNT_POINT"; fi
  if lvdisplay "/dev/${VG_NAME}/${SNAP_NAME}" >/dev/null 2>&1; then lvremove -f "/dev/${VG_NAME}/${SNAP_NAME}"; fi
}
trap cleanup EXIT

# Garante mountpoint
install -d -m 0755 "$MOUNT_POINT"

# Carrega variáveis do Restic
set -a
. /etc/restic.env
set +a

LV_PATH="/dev/${VG_NAME}/${LV_NAME}"
SNAP_PATH="/dev/${VG_NAME}/${SNAP_NAME}"

# (Opcional) Freeze curto do FS se souber o mount do LV original
# fsfreeze -f / && trap 'fsfreeze -u /; cleanup' EXIT  # Exemplo perigoso; ajuste ao seu mount real

# Cria snapshot copy-on-write
lvcreate -s -L "$SNAP_SIZE" -n "$SNAP_NAME" "$LV_PATH"

# Descongela se tiver congelado
# fsfreeze -u /

# Monta snapshot como readonly
mount -o ro "$SNAP_PATH" "$MOUNT_POINT"

# Executa backup incremental com Restic
HOSTNAME_FQDN="$(hostname -f || hostname)"
ionice -c2 -n7 nice -n 10 \
restic backup \
  --host "$HOSTNAME_FQDN" \
  --tag "$BACKUP_TAGS" \
  --exclude-file=/etc/restic/excludes.txt \
  "$MOUNT_POINT"

# (Opcional) Verificação rápida de integridade do último snapshot
restic snapshots --last --compact

# Cleanup é feito no trap

Agendamento com systemd: service + timers (backup e retenção)

Vamos criar unidades do systemd para orquestrar o backup e a retenção. O timer diário roda o backup; o semanal aplica retenção e prune. Use RandomizedDelaySec para evitar pico simultâneo em vários hosts.

Se você ainda usa cron, confira como migrar no guia Migrar cron para systemd timers.

# /usr/local/sbin/backup-lvm-restic.sh deve estar executável
chmod +x /usr/local/sbin/backup-lvm-restic.sh

# Unidade de backup
cat > /etc/systemd/system/backup-lvm-restic.service <<'EOF'
[Unit]
Description=Backup com LVM snapshot + Restic para S3
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/restic.env
ExecStart=/usr/local/sbin/backup-lvm-restic.sh
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=7
UMask=0077

[Install]
WantedBy=multi-user.target
EOF

# Timer diário do backup
cat > /etc/systemd/system/backup-lvm-restic.timer <<'EOF'
[Unit]
Description=Agendamento diário do backup LVM+Restic

[Timer]
OnCalendar=02:30
RandomizedDelaySec=20m
Persistent=true

[Install]
WantedBy=timers.target
EOF

# Serviço de retenção e prune semanal
cat > /etc/systemd/system/restic-prune.service <<'EOF'
[Unit]
Description=Restic forget+prune (retenção)
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/restic.env
ExecStart=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
UMask=0077
EOF

# Timer semanal de retenção (domingo 03:30)
cat > /etc/systemd/system/restic-prune.timer <<'EOF'
[Unit]
Description=Agendamento semanal Restic prune

[Timer]
OnCalendar=Sun *-*-* 03:30:00
RandomizedDelaySec=30m
Persistent=true

[Install]
WantedBy=timers.target
EOF

# Aplica e inicia timers
systemctl daemon-reload
systemctl enable --now backup-lvm-restic.timer
systemctl enable --now restic-prune.timer

# Primeira execução manual (opcional)
# systemctl start backup-lvm-restic.service

Verificação, restauração rápida e boas práticas

Valide a execução dos timers, examine logs do journal e confirme snapshots no repositório. Faça um restore de amostra para testar o caminho de recuperação. Teste antes de precisar.

Se você centraliza logs, integre o journal com ferramentas como no guia Fluentd + Elasticsearch: logs PHP em VPS (guia).

  • Confirme timers ativos e próxima execução.
  • Cheque logs do serviço e saída do Restic.
  • Liste snapshots e tags.
  • Restaure um arquivo/diretório de teste para validar chaves e permissão de acesso.
  • Automatize testes periódicos de restore em ambiente isolado.
# Timers e próximas execuções
systemctl list-timers | grep -E 'backup-lvm-restic|restic-prune'

# Logs da última execução do backup
journalctl -u backup-lvm-restic.service -n 200 --no-pager

# Lista snapshots
set -a; . /etc/restic.env; set +a
restic snapshots --compact

# Restauração de teste (ex.: arquivo do /etc)
mkdir -p /tmp/restore-test
restic restore latest --target /tmp/restore-test --include etc/hosts
ls -l /tmp/restore-test/etc/hosts

Solução de problemas comuns

Erros frequentes envolvem espaço insuficiente para snapshot, credenciais inválidas e locks pendentes no repositório. Abaixo, sintomas e ações. Nunca force remoções em LVM no volume errado.

Em sistemas com escrita intensa, aumente o SNAP_SIZE ou reduza a janela do backup. Confirme DNS/firewall para alcançar o endpoint S3.

  • Snapshot fica cheio/invalidado: aumente SNAP_SIZE ou reduza a atividade de escrita durante o backup.
  • lvcreate falhou: confirme VG/LV corretos e espaço livre no VG (vgs/lvs).
  • Permissão S3 negada: valide política IAM e variáveis em /etc/restic.env.
  • Repositório trancado: use 'restic unlock' com cautela, assegurando que não há processos em execução.
  • Tempo de backup alto: ajuste excludes, use tags e agende fora do horário de pico.
# Diagnóstico LVM
vgs; lvs -a -o +devices

# Verificação de mountpoint do snapshot
mount | grep backup-snap || lsblk -f

# Teste de credenciais/ambiente do Restic
set -a; . /etc/restic.env; set +a
restic snapshots || echo "Verifique RESTIC_REPOSITORY e variáveis AWS"

# Remover lock do repositório com cuidado
restic unlock

# Logs detalhados
journalctl -u backup-lvm-restic.service --since "-2h" -e --no-pager

Perguntas frequentes

Qual tamanho devo usar para o snapshot LVM?

Depende da taxa de escrita durante a janela do backup. Quanto mais o volume muda, maior precisa ser o snapshot (área de copy‑on‑write). Comece com alguns gigabytes e ajuste após observar se o snapshot enche. Monitore nas primeiras execuções.

Posso usar endpoints compatíveis com S3?

Sim, o Restic trabalha com APIs compatíveis com S3 ao informar o endpoint na URL do repositório. Verifique requisitos de autenticação, região e TLS do provedor escolhido, e teste com restic init e restic snapshots antes de automatizar.

Backups de bancos de dados ficam consistentes com snapshot LVM?

O snapshot LVM garante consistência de bloco. Para consistência lógica da aplicação, faça um dump transacional ou um freeze rápido do filesystem/serviço (quando suportado) antes do lvcreate, e desfaz após a criação do snapshot. Avalie o impacto no seu workload.

Como faço retenção sem perder os backups úteis?

Use restic forget com política adequada ao negócio, seguida de prune. Por exemplo, manter 7 diários, 4 semanais e 6 mensais. Ajuste aos seus RPO/RTO. Sempre teste restaurações após alterar políticas para conferir se atendem ao objetivo.

É seguro manter as credenciais no /etc/restic.env?

Sim, desde que o arquivo tenha permissões restritas (0600) e acesso apenas por root. Considere separar o usuário que roda o Restic quando não precisar de privilégios elevados, e rotacione chaves IAM periodicamente.

Quanto custará armazenar no S3?

Varia com volume total em GB, número de objetos/versões, requisições e região do bucket. Uploads incrementais e retenção adequada reduzem custo. Verifique preços atuais diretamente no site do provedor e ajuste a política de retenção conforme necessário.

Precisa adaptar o backup ao seu ambiente?

Se quiser revisar política de retenção, exclusões e janelas de execução para sua carga de trabalho, entre em contato e descreva seu cenário.

Conversar sobre backup e automação

Veja também