Tutorial de Linux / Automatize backups e verifique a saúde do servidor

A operação confiável exige backups recuperáveis e verificações que revelem falhas. Valide separadamente a criação do arquivo, a integridade, a restauração, a resposta HTTP e o espaço disponível; mantenha também uma forma externa de detectar falhas ou ausência de execução.

Conecte o procedimento comprovado na verificação manual de backup e restauração à execução agendada. Confirme separadamente a criação, a restauração independente e a comunicação de falhas.

As referências deste exercício são VMs convencionais Ubuntu 26.04 LTS ou Rocky Linux 9. Contêineres, WSL e outras versões podem ter serviços e pacotes diferentes. Prepare recuperação pelo console e registre as versões seguindo a aula de preparação da máquina virtual, em inglês.

Defina os dados e o alcance da recuperação

O exemplo trata arquivos estáticos comuns, com alterações controladas, como o conteúdo da aula de Nginx. Faça backup separado das configurações de serviço, certificados, informações DNS e procedimentos de implantação; para bancos de dados, use ferramentas que garantam consistência da aplicação. O arquivo local demonstra o fluxo, mas não protege por si só contra falha do disco do servidor ou comprometimento da conta.

Escolha uma origem legível pelo usuário e um diretório de backup privado e gravável. Não agende tudo como root apenas para contornar permissões. Em produção, planeje conta dedicada, caminhos permitidos, chaves de criptografia e retenção.

Crie um script de backup com origem e destino explícitos

Antes de criar os scripts, confira se $HOME/bin/course-backup.sh e $HOME/bin/course-health.sh já existem ou são links simbólicos: os redirecionamentos os sobrescrevem. Se houver conflito, escolha nomes novos e ajuste todos os comandos e unidades de agendamento. Não execute em dados importantes até testar em diretórios próprios e controlados.

Para este exemplo, use uma pasta de origem de laboratório que não seja / e um diretório de backup separado dela. A comparação textual de caminhos do script não protege todos os casos de montagens, caminhos alternativos ou alterações simultâneas; em particular, não confie nela para impedir que um destino dentro da raiz / seja incluído no próprio backup. Confirme a separação real dos caminhos e dos sistemas de arquivos antes de executar.

mkdir -p "$HOME/bin"
cat > "$HOME/bin/course-backup.sh" <<'EOF'
#!/usr/bin/env bash
set -u
set -o pipefail
umask 077
if (( $# != 2 )); then
  printf "Usage: %s SOURCE_DIRECTORY BACKUP_DIRECTORY\n" "$0" >&2
  exit 2
fi
source_dir=$(realpath -e -- "$1") || exit 1
backup_dir=$(realpath -e -- "$2") || exit 1
[[ -d "$source_dir" && -d "$backup_dir" ]] || exit 1
case "$backup_dir/" in
  "$source_dir/"*) printf "Backup must be outside source\n" >&2; exit 1 ;;
esac
work=$(mktemp -d "$backup_dir/backup.XXXXXXXX") || exit 1
if ! tar -czf "$work/data.tar.gz" -C "$source_dir" .; then
  printf "Archive failed: %s\n" "$work" >&2; exit 1
fi
if ! tar -tzf "$work/data.tar.gz" > /dev/null; then
  printf "Archive listing failed\n" >&2; exit 1
fi
if ! (cd "$work" && sha256sum data.tar.gz > data.tar.gz.sha256); then
  printf "Checksum creation failed\n" >&2; exit 1
fi
if ! date --iso-8601=seconds > "$work/created-at.txt"; then exit 1; fi
printf "complete\n" > "$work/COMPLETE" || exit 1
printf "Backup ready: %s\n" "$work"
EOF
bash -n "$HOME/bin/course-backup.sh"

O script cria uma pasta exclusiva por execução, evitando colisão de nomes. Considere concluídos somente os arquivos com o marcador final COMPLETE; ele indica que essas etapas terminaram, não que a restauração da aplicação foi comprovada. Falhas podem deixar diretórios parciais para investigação: não os inclua como pontos de recuperação. A data é registrada, mas backups antigos não são apagados automaticamente.

Teste criação, integridade e restauração separadamente

Execute as linhas na mesma sessão e pare se alguma falhar. Confirme que mktemp criou uma pasta nova antes de prosseguir; não deixe os comandos seguintes agir com lab vazio.

lab=$(mktemp -d "$HOME/linux-ops-lab.XXXXXX")
mkdir "$lab/site" "$lab/backups" "$lab/restored"
printf "site version 1\n" > "$lab/site/index.html"
bash "$HOME/bin/course-backup.sh" "$lab/site" "$lab/backups"
find "$lab/backups" -maxdepth 2 -type f -print

Substitua ACTUAL_BACKUP_DIRECTORY no bloco pelo caminho real impresso após Backup ready:; se contiver espaços, atribua-o entre aspas. A soma de controle e a listagem do arquivo tar não comprovam recuperação da aplicação: compare o conteúdo restaurado e teste o serviço web separadamente.

backup=ACTUAL_BACKUP_DIRECTORY
test -f "$backup/COMPLETE"
(cd "$backup" && sha256sum -c data.tar.gz.sha256)
tar -xzf "$backup/data.tar.gz" -C "$lab/restored"
diff -r "$lab/site" "$lab/restored"

Espera-se o marcador, uma verificação de soma com OK e nenhuma diferença em diff. Restaure em diretório vazio e verifique permissões, proprietário e rótulos necessários. Depois da transferência para armazenamento independente, repita a verificação e o teste de restauração. Quando o espaço estiver escasso, aplique uma retenção que preserve os pontos necessários em vez de apagar cópias antigas indiscriminadamente.

Crie uma verificação de HTTP e espaço disponível

São necessários curl, df e awk. O script recebe URL, limite mínimo de espaço em KiB e caminho de armazenamento; considera HTTP 200–299 saudável. Ajuste o critério se o serviço deve redirecionar ou exigir autenticação. A verificação não confirma o conteúdo da página, o estado do banco de dados nem todas as funções da aplicação.

cat > "$HOME/bin/course-health.sh" <<'EOF'
#!/usr/bin/env bash
set -u
set -o pipefail
if (( $# != 3 )); then
  printf "Usage: %s URL MIN_FREE_KIB STORAGE_PATH\n" "$0" >&2; exit 2
fi
url=$1
minimum=$2
path=$3
[[ "$minimum" =~ ^[0-9]+$ ]] || exit 2
if ! status=$(curl -sS -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 15 "$url"); then
  printf "HTTP transport failed\n" >&2; exit 1
fi
[[ "$status" =~ ^2[0-9][0-9]$ ]] || { printf "HTTP status=%s\n" "$status" >&2; exit 1; }
available=$(df -Pk -- "$path" | awk 'NR==2 {print $4}') || exit 1
[[ "$available" =~ ^[0-9]+$ ]] || exit 1
(( 10#$available >= 10#$minimum )) || { printf "Low storage: %s KiB\n" "$available" >&2; exit 1; }
printf "OK http=%s free_kib=%s\n" "$status" "$available"
EOF
bash -n "$HOME/bin/course-health.sh"
bash "$HOME/bin/course-health.sh" http://127.0.0.1/ 102400 "$HOME"

O limite de 102400 KiB equivale a cerca de 100 MiB e é ilustrativo, não uma recomendação operacional. Escolha-o conforme crescimento e espaço para recuperação e confira inodes separadamente. Para um site Nginx por nome, use a URL real ou a rota Host apropriada: um 200 da página padrão não valida o site pretendido.

Agende a tarefa e detecte falhas de forma independente

Reutilize a estrutura de serviço e timer de usuário da aula 29, com ExecStart chamando /bin/bash %h/bin/course-backup.sh ORIGEM_REAL DESTINO_REAL. Para caminhos com espaços, use aspas conforme a sintaxe do systemd e teste primeiro o mesmo comando manualmente. Escolha a frequência de acordo com os objetivos de recuperação e mantenha a verificação de saúde em outra unidade.

Confira separadamente o próximo disparo, o estado de saída do serviço e a hora do último backup concluído. Um monitor no mesmo servidor para junto com ele; outro monitor fora do servidor deve verificar a URL real e a atualidade do backup. Teste a entrega de alertas de e-mail ou mensagens e defina responsáveis e ações de recuperação para cada falha relevante.

Teste falhas e remova o laboratório

Altere uma condição por vez: origem inexistente, recurso HTTP inexistente e limite de espaço propositalmente alto. Restaure cada valor e confirme que arquivos incompletos não são reportados como sucesso. Desative os timers de laboratório antes de remover somente os scripts e diretórios de trabalho criados para este exercício.

Referências oficiais