Files
SavaneWiki/docs/Savaneprod/2020-12-04-borg-backup.md
jf 1010c0df9e
All checks were successful
continuous-integration/drone/push Build is passing
Update docs/Savaneprod/2020-12-04-borg-backup.md
2025-04-27 08:33:45 +02:00

5.8 KiB

title, authors, date
title authors date
Sauvegarde externalisée grâce à Borg Backup
JF
2020-12-04

La sauvegarde de savanecloud.fr

J'ai découvert "Borg" lors du stage concluant ma formation de reconversion professionnelle. L'outil est simple, efficace, disponible sur Synology DSM et il existe des fournisseurs de services spécialisés chez lesquels, on peut externaliser nos sauvegardes. Mais me direz-vous pourquoi externaliser des sauvegardes ? Beh ouais, avec un NAS en RAID 1 j'ai peu de risque de perdre mes données. Effectivement. Mais le risque existe. Matérialisé par un cambriolage ou une destruction malencontreuse dudit NAS. Bref. Un jour j'ai eu peur et j'ai pris au sérieux la sauvegarde en dehors du cadre professionnel. Et bien entendu, laisser faire le boulot par Google, Dropbox, feu Hubic ou Microsoft ne me plaisais pas beaucoup.

Installation de Borg sur le Synology

Le dépot de Synocommunity

Le paquet n'est pas disponible par défaut dans le dépôt ("repository", dire "ripo" pour les franglophones) de DSM. Pour l'obtenir, il faut ajouter un dépôt depuis les paramètres du gestionnaire de paquets de DSM. Le dépôt que j'utilise est celui de SynoCommunity. Ajout d'un dépôt dans le gestionnaire de paquets de DSM. Ensuite il suffit de raffraîchir la liste des paquets disponibles et Borg Apparaît. Vous noterez en bas que Borg nécessite Python 3.11, cette dépendance est aussi à installer depuis le dépôt de SynoCommunity. Fiche descriptive du paquet Borg

Script de sauvegarde avec Borg

#!/bin/bash
SECONDS=0
SCRIPT_PATH="$(dirname $(readlink -f $BASH_SOURCE))"
alias borg="/usr/local/bin/borg"


BORG_VARIABLES="/volume1/root_only/Backup/nextcloud/BORG_VARIABLES.secret"
if [[ ! -f $BORG_VARIABLES ]]
then
  printf "Create the BORG_VARIABLES.secret file."
  exit 2
fi
source $BORG_VARIABLES

: << 'BORG_VARIABLES.secret'
main_dir=""
export BORG_RSH='' # ssh options ex: 'ssh -i /.ssh/id_rsa'
export BORG_REPO='borgserver:/borgrepo'
export BORG_PASSCOMMAND="cat $main_dir/BORG_PASSPHRASE.secret"
export BORG_BASE_DIR="$main_dir/BORG_BASE_DIR"
directories_to_backup=""
directories_to_exlude=""
logfile_path="$main_dir/logs"
BORG_VARIABLES.secret
 

#######################################################

[[ ! -d logfile_path ]] && mkdir -p $logfile_path

logfile_name="$(date +%Y-%m-%d--%Hh%M)_borgbase.log"
logfile="$logfile_path/$logfile_name"


# Logging destination management
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>$logfile 2>&1 | tee -a $logfile

: << 'EXPLANATION'
https://serverfault.com/questions/103501/how-can-i-fully-log-all-bash-scripts-actions
    exec 3>&1 4>&2
    Saves file descriptors so they can be restored to whatever they were before redirection or used themselves to output to whatever they were before the following redirect.
    trap 'exec 2>&4 1>&3' 0 1 2 3
    Restore file descriptors for particular signals. Not generally necessary since they should be restored when the sub-shell exits.
    exec 1>log.out 2>&1
    Redirect stdout to file log.out then redirect stderr to stdout. Note that the order is important when you want them going to the same file. stdout must be redirected before stderr is redirected to stdout.
From then on, to see output on the console (maybe), you can simply redirect to &3. For example,
echo "$(date) : part 1 - start" >&3
will go to wherever stdout was directed, presumably the console, prior to executing line 3 above.
EXPLANATION

render_time () {
  local T=$1
  local H=$((T/60/60%24))
  local M=$((T/60%60))
  local S=$((T%60))
  local r=''
  [[ $H > 0 ]] && r=$(printf '%d hours ' $H)
  [[ $M > 0 ]] && r+=$(printf '%d minutes ' $M)
  [[ $H > 0 || $M > 0 ]] && r+=$(printf 'and ')
  r+=$(printf '%d seconds' $S)
  echo $r
}

afficher () {
  local STARS="***************************************************************************"
  if [[ $2 != "notime" ]]
  then printf '%s\n\t%s elapsed -- %s \n\t%s\n%s\n' "$STARS" "$(render_time $SECONDS)" "$(date +%c)" "$1" "$STARS"
  else printf '%s\n\t%s\n%s\n' "$STARS" "$1" "$STARS"
  fi
}


nextcloud_maintenance () {
  docker exec -u www-data nextcloud_app_1 php occ maintenance:mode --$1
  [[ $1 = "on" ]] && sleep 1m
}

file_exists_or_explain () {
  if [[ ! -f $1 ]]
  then
    printf '%s does not exist.\n%s\n' "$1" "$2"
    exit 2
  fi
}



nextcloud_bkup () {
  # borg init --encryption=repokey --storage-quota 200G 

  afficher  "Début de la sauvegarde du $(date +%c)" "notime"

  afficher "Borg info"
  borg info 

#  afficher "Borg delete"
#  /usr/local/bin/borg delete --glob-archive '*'

  afficher "Mise en maintenance du nextcloud"
  nextcloud_maintenance "on"
  
  afficher "Dump de la base de données Postgres..."
  docker exec nextcloud_db_1 /usr/bin/pg_dump -U nextcloud nextcloud | gzip > /volume1/nextcloud/db_dump.sql.gz
  # Restaurer la BDD
  # docker exec nextcloud_db_1 pg_restore -U postgres -d nexcloud /backups/db_dump.sql 
  
  afficher "Sauvegarde BorgBase..."
  borg create \
  --stats \
  --compression lz4 \
  ::{now:%Y-%m-%d--%Hh%M} \
  $directories_to_backup \
--exclude $directories_to_exclude
  
  afficher "Fin de la maintenance nextcloud."
  nextcloud_maintenance "off"
  
  afficher "Borg prune"
  # Keep 7 end of day, 0 additional end of week archives, and 6 end of month archive
  borg prune -v --list --stats --keep-daily=15 --keep-weekly=0 --keep-monthly=3 
  afficher "Fin de borg prune"
  
  afficher "Borg info"
  # Pour le mail envoyé en fin par le Task Scheduler Synology
  borg info 

}

# Removes everyting from the repo
#/usr/local/bin/borg delete --glob-archive '*'

nextcloud_bkup

printf "La sauvegarde a mis %s à s'exécuter." "$(render_time $SECONDS)"

exit 1

Le service qui me permet d'externaliser facilement les sauvegardes, est BorgBase.