Ferramentas

Borg como solução de backup.

Launchd para criação de backups periódicos

Passos

  • Criar um repositório do Borg: Será armazenado nesse diretório todos os backups feitos e seus snapshots incrementais.
    • borg init -e=repokey ~/home-backup
  • (opcional) Exclusão / Inclusão de arquivos no backup: Pode-se criar um arquivo para incluir ou excluir arquivos ou diretórios do backup.
  • Comando para criar os backups:
    • borg create --progress --stats --patterns-from ~/borg-backup-home.lst ~/home-backup::'{now}'
  • Listando os backups:
    • borg list ~/home-backup
  • Compactando os backups: Rode o seguinte comando para compactar os backups eliminando segmentos não utilizados.
    • borg compact /Users/my-user/home-backup
  • Prune os backups: Para limpeza dos backups antigos ou repetidos, pode-se usar o comando prune:
    • borg prune --keep-within=2d --keep-daily=7 --keep-weekly=8 --keep-monthly=12 --keep-yearly=3 ~/home-backup
    • A explicação desse comando pode ser vista em Explicação do comando prune
  • (opcional) Sync do backup para um bucket: Para enviar para a nuvem, pode usar um serviço do tipo “Google Drive” / “Dropbox” ou subir em um bucket. Exemplo:
    • gsutil rsync -d ~/home-backup gs://my-bucket
  • Automatizar backup e sync: No OsX (Mac), pode-se usar o Launchd para realizar o backup periodicamente. Para isso

Outros

Shell para backup

Pode-se guarda-lo em ~/borg-home-backup.sh

#!/usr/bin/env bash
 
export BORG_PASSPHRASE="my-passprase"
 
/opt/homebrew/bin/borg create --progress --stats --patterns-from /Users/my-user/borg-backup-home.lst /Users/my-user/home-backup::'{now}'
/opt/homebrew/bin/borg prune --keep-daily=5 --keep-weekly=14 --keep-monthly=4 --keep-yearly=12 /Users/my-user/home-backup
/opt/homebrew/bin/borg compact /Users/my-user/home-backup
 
echo "Syncing to GCP Bucket"
 
/Users/my-user/google-cloud-sdk/bin/gsutil rsync -d ~/home-backup gs://my-backup-bucket
 
# OR
aws s3 sync /Users/my-user/home-backup/ s3://my-bucket/ --delete

Arquivo launchd para macosx

Crie o arquivo abaixo que periodicamente o shell ~/borg-home-backup.sh

Este serviço é programado para iniciar em quatro momentos diferentes no decorrer do dia, especificamente às 10:00, 13:00, 18:00 e 20:00.

Além disso, qualquer saída padrão ou erro gerado pelo serviço será redirecionado para dois arquivos diferentes localizados no diretório “/tmp”, nomeados como “com.alisson.borg.out” e “com.alisson.borg.err”, respectivamente.

Pode-se guarda-lo em ~/Library/LaunchAgents/com.alisson.borg.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.alisson.borg</string>
 
	    <key>EnvironmentVariables</key>
	    <dict>
	      <key>PATH</key>
	      <string>/opt/homebrew/opt/gnu-getopt/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin</string>
	      <key>HOME</key>
	      <string>/Users/SEU_USUARIO</string>
	      <key>GNUPGHOME</key>
	      <string>/Users/SEU_USUARIO/.gnupg</string>
        </dict>
 
        <key>ProgramArguments</key>
        <array>
            <string>/Users/my-user/borg-home-backup.sh</string>
        </array>
 
        <key>StartCalendarInterval</key>
        <array>
            <dict>
                <key>Hour</key>
                <integer>10</integer>
                <key>Minute</key>
                <integer>0</integer>
            </dict>
            <dict>
                <key>Hour</key>
                <integer>13</integer>
                <key>Minute</key>
                <integer>0</integer>
            </dict>
            <dict>
                <key>Hour</key>
                <integer>18</integer>
                <key>Minute</key>
                <integer>0</integer>
            </dict>
            <dict>
                <key>Hour</key>
                <integer>20</integer>
                <key>Minute</key>
                <integer>0</integer>
            </dict>
        </array>
 
        <key>StandardOutPath</key>
        <string>/tmp/com.alisson.borg.out</string>
        <key>StandardErrorPath</key>
        <string>/tmp/com.alisson.borg.err</string>
    </dict>
</plist>

Carregar / ativar o serviço

LaunchAgents são serviços de nível de usuário — não usar sudo (caso contrário o launchctl espera um caminho de LaunchDaemons e falha).

# Carregar (sintaxe legada, ainda funciona)
launchctl load ~/Library/LaunchAgents/com.alisson.borg.plist
 
# Carregar (sintaxe moderna recomendada)
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.alisson.borg.plist

Descarregar / desativar o serviço

# Sintaxe legada
launchctl unload ~/Library/LaunchAgents/com.alisson.borg.plist
 
# Sintaxe moderna
launchctl bootout gui/$(id -u)/com.alisson.borg

Recarregar (descarregar e carregar novamente)

launchctl bootout gui/$(id -u)/com.alisson.borg
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.alisson.borg.plist

Verificar status

# Listar serviço e ver se está rodando
launchctl list | grep com.alisson.borg
 
# Detalhes do serviço (erros, última execução, etc.)
launchctl print gui/$(id -u)/com.alisson.borg

⚠️ Erro comum: usar sudo launchctl load com LaunchAgents causa Input/output error. Sempre use sem sudo para agentes em ~/Library/LaunchAgents/.

Arquivo para exclusão / inclusão

Pode-se guarda-lo em ~/borg-backup-home.lst

R /Users/my-user/

# Any inside dir...
- **/cache
- **/cache-chat
- **/.git
- **/node_modules

# Emacs temp
- **/*~
- **/\#*

# borg backup script (it has passphrase)
- /Users/my-user/borg-home-backup.sh

# Dirs from home
- /Users/my-user/.docker
- /Users/my-user/.pyenv
- /Users/my-user/.nuget
- /Users/my-user/.nvm
- /Users/my-user/.npm
- /Users/my-user/.vscode
- /Users/my-user/.local

- /Users/my-user/Applications
- /Users/my-user/javasharedresources
- /Users/my-user/nltk_data
- /Users/my-user/google-cloud-sdk
- /Users/my-user/go
- /Users/my-user/confluent
- /Users/my-user/home-backup # backup itself
- /Users/my-user/Library

# Personal workspace temp dir (trash things...)
- /Users/my-user/wo/personal/temp

# dirs with data from kafka (messages in files)
- **/kafka-consumer/data-*

Explicação do comando prune

Exemplo: borg prune --keep-within=2d --keep-daily=7 --keep-weekly=8 --keep-monthly=12 --keep-yearly=3 ~/home-backup

Explicação:

Este comando é usado para podar (ou seja, excluir) backups antigos.

Aqui está o que cada opção faz:

--keep-within=2d: Mantém todos os backups feitos dentro dos últimos 2 dias (48h). --keep-daily=7: Mantém um backup diário pelos últimos 7 dias. --keep-weekly=8: Mantém um backup semanal pelas últimas 8 semanas. --keep-monthly=12: Mantém um backup mensal pelos últimos 12 meses. --keep-yearly=3: Mantém um backup anual pelos últimos 3 anos.

O último argumento ~/home-backup é o diretório que contém os backups.

Portanto, este comando irá excluir todos os backups que não se enquadrem nessas regras.

Gerenciamento de Chaves e Criptografia

O Borg usa criptografia AES-256 em duas camadas:

Passphrase (você memoriza/guarda)
    └─► decripta ──► Repository Key (AES-256)
                         └─► decripta ──► dados dos backups

Modos de criptografia

ModoOnde a chave ficaQuando usar
repokey-blake2No próprio repositórioRecomendado — maioria dos casos
keyfile-blake2Só na máquina cliente (~/.config/borg/keys/)Servidor não confiável (ex: cloud)
noneRepositórios locais sem necessidade de sigilo

Diferença crucial: no modo repokey, a chave cifrada fica embutida no repositório. No modo keyfile, a chave não está no repositório — sem ela e a passphrase, os dados são inacessíveis mesmo com acesso total ao servidor.

Exportar a chave (faça isso logo após criar o repo)

# Exportar como arquivo
borg key export /path/to/repo ~/borg.key
 
# Exportar em formato legível por humanos (para imprimir/papel)
borg key export --paper /path/to/repo

⚠️ Com keyfile, se perder a máquina sem esse export, perde os dados para sempre.

Proteger a chave exportada com GPG

gpg --symmetric --cipher-algo AES256 ~/borg.key
shred -u ~/borg.key  # apagar versão em texto plano
# guarde o borg.key.gpg em local separado do repositório

Trocar passphrase

borg key change-passphrase /path/to/repo

Automação sem expor a passphrase em texto plano

Evite BORG_PASSPHRASE="texto" direto no script. Prefira:

# Via arquivo com permissão restrita
export BORG_PASSPHRASE_FILE=/root/.borg-passphrase  # chmod 400
 
# Via GPG (requer gpg-agent rodando)
export BORG_PASSPHRASE=$(gpg --quiet --batch --decrypt ~/.safe/borg-pass.gpg)

⚠️ O script de backup atual (~/borg-home-backup.sh) expõe a passphrase em texto plano — considere migrar para uma das opções acima.

Verificar integridade do repositório

borg check /path/to/repo              # verificação rápida (metadados)
borg check --verify-data /path/to/repo  # completa (mais lento)

Checklist de disaster recovery

Guarde em local seguro (gerenciador de senhas, cofre):

  • Passphrase do repositório
  • Export da chave (borg key export)
  • Endereço/caminho do repositório
  • Versão do Borg usada
  • Comando para restaurar: borg mount /repo /mnt/borg