⌘K

09 – Automação de Backups: Criando um Script robusto para Produção (Sem expor senhas!)

Last updated

Até este ponto da nossa série Guia de Sobrevivência: Backup e Manutenção no Postgres, nós aprendemos a teoria, dominamos as flags cirúrgicas do pg_dump, desvendamos a velocidade do pg_restore e limpamos a casa com o vacuumdb.

Mas convenhamos: ninguém quer acordar às 3h da manhã para rodar comandos de backup manualmente. Em um ambiente de produção real, a automação não é apenas uma conveniência, é uma apólice de seguro.

Hoje, vamos colocar o chapéu de DevOps/SysAdmin e construir um script de automação industrial para o seu pipeline de infraestrutura. Nosso script vai gerar o backup, compactar os dados, registrar logs detalhados de sucesso ou erro, aplicar políticas de retenção (rotação de arquivos antigos) e, para fechar com chave de ouro, enviar o resultado para um storage externo em nuvem (como um bucket AWS S3).

O Gancho: O Perigo de Expor Senhas no Script

Antes de olhar para o código, vamos resolver a maior falha de segurança que os robôs de varredura do GitHub encontram em repositórios corporativos: expor credenciais em texto puro dentro de scripts de automação.

Escrever algo como pg_dump -U meu_usuario -p MinhaSenha123 ... dentro de um arquivo .sh ou .py é um risco grave de segurança. Se alguém tiver acesso de leitura ao servidor (ou ao repositório de código), seu banco estará comprometido.

Para resolver isso de forma elegante e nativa, o PostgreSQL nos dá o arquivo .pgpass.

Como funciona o .pgpass?

O cliente do Postgres (incluindo o pg_dump) procura automaticamente por um arquivo oculto chamado .pgpass na pasta do usuário que está executando o comando (no Linux, geralmente em ~/.pgpass).

O formato interno dele é extremamente simples e direto:

Plaintext

hostname:port:database:username:password

Configurando o seu acesso seguro:

No seu servidor de backup, crie o arquivo apontando para as credenciais de produção:

Bash

# Adiciona a credencial de forma segura
echo "localhost:5432:meu_banco_producao:backup_user:SenhaSecretaSuperForte" >> ~/.pgpass

# CRUCIAL: O Postgres exige que as permissões do arquivo sejam restritas ao dono
chmod 0600 ~/.pgpass

Nota: Se as permissões não forem exatamente 0600 (leitura e escrita apenas para o dono), o Postgres vai ignorar o arquivo por segurança. Agora, sempre que o usuário rodar o pg_dump, o sistema vai consultar o .pgpass em background e autenticar sem que nenhuma senha precise ser digitada na linha de comando ou exposta em variáveis visíveis no processo (ps aux).

O Script de Produção: Shell + AWS CLI

Aqui está um modelo de script Shell (backup_postgres.sh) pronto para rodar via cron no seu servidor. Ele foi desenhado seguindo as melhores práticas que discutimos nos posts anteriores (utilizando o formato Custom).

Bash

#!/usr/bin/env bash

# Exit imediatamente se um comando falhar, se houver variáveis não declaradas ou erro em pipes
set -euo pipefail

# ==========================================
# CONFIGURAÇÕES DO AMBIENTE
# ==========================================
DB_HOST="localhost"
DB_USER="backup_user"
DB_NAME="meu_banco_producao"
BACKUP_DIR="/opt/postgres/backups"
LOG_FILE="/var/log/postgres_backup.log"

# Configurações do Storage em Nuvem (S3)
S3_BUCKET="s3://meu-bucket-backups-postgres/producao"
RETENCAO_DIAS=7
DATA_ATUAL=$(date +"%Y-%m-%d_%H-%M-%S")
NOME_ARQUIVO="${DB_NAME}_${DATA_ATUAL}.dump"
PATH_FINAL="${BACKUP_DIR}/${NOME_ARQUIVO}"

# Garante que o diretório local existe
mkdir -p "$BACKUP_DIR"

# Função de Log com timestamp
log_message() {
    echo "$(date +"%Y-%m-%d %H:%M:%S") - $1" >> "$LOG_FILE"
}

# ==========================================
# EXECUÇÃO DO BACKUP
# ==========================================
log_message "Iniciando o backup do banco de dados: ${DB_NAME}..."

# Executa o pg_dump usando o formato Custom (-F c). A senha virá do ~/.pgpass de forma segura.
if pg_dump -h "$DB_HOST" -U "$DB_USER" -F c -b -v -f "$PATH_FINAL" "$DB_NAME" 2>> "$LOG_FILE"; then
    log_message "Backup local gerado com sucesso: ${NOME_ARQUIVO}"
else
    log_message "ERRO CRÍTICO: Falha ao gerar o pg_dump local. Verifique os logs."
    exit 1
fi

# ==========================================
# ENVIO PARA A NUVEM (AWS S3)
# ==========================================
log_message "Iniciando upload para o AWS S3..."

if aws s3 cp "$PATH_FINAL" "${S3_BUCKET}/${NOME_ARQUIVO}" 2>> "$LOG_FILE"; then
    log_message "Upload concluído com sucesso para o S3!"
else
    log_message "ERRO CRÍTICO: Falha no upload para o S3."
    exit 1
fi

# ==========================================
# POLÍTICA DE RETENÇÃO (ROTAÇÃO LOCAL)
# ==========================================
log_message "Aplicando política de rotação. Removendo arquivos locais mais velhos que ${RETENCAO_DIAS} dias..."

# Encontra arquivos .dump modificados há mais de X dias no diretório e os remove
find "$BACKUP_DIR" -type f -name "*.dump" -mtime +"$RETENCAO_DIAS" -exec rm -f {} \;

log_message "Rotação local concluída. Rotina finalizada com sucesso."
echo "--------------------------------------------------------" >> "$LOG_FILE"

Como agendar no Servidor (Cron)

Para colocar essa rotina rodando todas as noites, por exemplo, às 02:00 da manhã (horário de menor tráfego da aplicação), basta adicionar o script na tabela de tarefas do Linux (crontab):

Bash

# Abra o editor de tarefas do usuário atual
crontab -e

Adicione a seguinte linha no final do arquivo:

Plaintext

0 2 * * * /bin/bash /opt/postgres/scripts/backup_postgres.sh > /dev/null 2>&1

Anatomia de uma Automação Resiliente

Se você preferir escrever essa lógica utilizando Python, o princípio de segurança permanece o mesmo: use o módulo subprocess para chamar o pg_dump e a biblioteca boto3 para gerenciar a integração com o S3. O Python oferece vantagens se você precisar integrar o alerta de falhas diretamente com uma API de mensageria (como enviar um card no Microsoft Teams, Slack ou um alerta no PagerDuty caso o script retorne exit 1).

Independentemente da linguagem, um script de produção sênior obrigatoriamente precisa contemplar:

  1. Redirecionamento de Logs (2>> log.txt): Capturar a saída de erro do Postgres para entender o que quebrou se o dump falhar.
  2. Isolamento de Credenciais: Nunca colocar strings de autenticação expostas no código principal.
  3. Armazenamento Descentralizado: Manter o backup no mesmo disco físico do banco de dados não protege você caso o servidor inteiro sofra uma avaria de hardware. O envio para a nuvem é mandatório.

Conclusão

Criar um script de backup seguro e automatizado é o marco divisor entre uma infraestrutura amadora e um ambiente resiliente pronto para produção. Com o arquivo .pgpass configurado e o script rodando no Cron, você tira o fator humano do processo.

Mas o seu plano de recuperação de desastres está realmente concluído?

No próximo e último post da nossa série, vamos abordar o teste definitivo de sanidade: como criar um “Checklist de Desastre” automatizado para validar se os seus arquivos gerados pelo script não estão corrompidos e estão realmente prontos para salvar a empresa em caso de caos. Não perca o encerramento da nossa jornada!

Como funciona a automação de backups no seu ambiente hoje? Você já conhecia o truque do .pgpass ou costuma passar a senha direto no script? Compartilhe nos comentários!

Still stuck? How can we help? Get Help