Restic + Backrest + MiniO - 2

· 6 min · @Self-Hosting · #unRAID #Docker

Continuamos con esta segunda parte donde explicaremos cómo sacar provecho de estas 3 aplicaciones. En este caso, explicaré el script que estoy usando para realizar las copias, que es una variación de uno que tiene Lorenzo en su GitHub, pero que en mi caso, en vez de ser un fichero jinja, es un fichero en Bash a pelo.

nota: No entiendo el sentido que tiene utilizar los ficheros jinja. Sé que es una plantilla para la creación de un fichero al vuelo, pero cómo utilizarlos es lo que se me escapa. Ya le preguntaremos a Lorenzo su función o a ver si tiene algún podcast donde lo explique.

Aquí tenéis el script que estoy usando ahora mismo (versionado del original de atareao) pero para mis necesidades.

nota: Esta primera parte es la función del script, la cual se encarga de enviar las notificaciones, ahora sí, a mi servidor de Matrix.

# Funció per a notificar les accions del script
enviarNotificacions(){
    local repository="$1"
    local action="$2"
    local data="$3"

    local result=""
    local formatted_message="<strong>📢 Resumen de respaldo:</strong><br>"
    formatted_message+="<strong>🗂 Repositorio:</strong> ${repository}<br>"
    formatted_message+="<strong>⚡ Acción:</strong> ${action}<br>"
    formatted_message+="<strong>📦 Archivos procesados:</strong><br><pre>"

    while read -r line; do
        [[ -n "$line" ]] && result+="${line}<br />"
    done < <(echo "$data")

    formatted_message+="${result}</pre>"

    # Tria el final de cada missatge segons l'acció que s'ha dut a terme
    case "$action" in
        create) formatted_message+="<strong>💾 End backup at ${repository}</strong>" ;;
        check) formatted_message+="<strong>🔍 End check at ${repository}</strong>" ;;
        prune) formatted_message+="<strong>🗑️ End prune at ${repository}</strong>" ;;
        snapshots) formatted_message+="<strong>📸 End snapshots at ${repository}</strong>" ;;
    esac

    # Escapar caracters especials adequadament
    formatted_message=$(echo "$formatted_message" | sed -E 's/"/\\"/g')

    # Construcció manual del JSON verificant que tot estigui en una sola linia
    json_payload=$(printf '{"msgtype":"m.text","format":"org.matrix.custom.html","formatted_body":"%s"}' "$formatted_message")

    # Enviem la notificació fent servir CURL
    curl -X PUT \
        -H "Authorization: Bearer ${MATRIX_TOKEN}" \
        -H "Content-Type: application/json" \
        -d "$json_payload" \
        "${MATRIX_SERVER}/_matrix/client/v3/rooms/${MATRIX_ROOM}/send/m.room.message/$(date '+%s%3N')"
}

nota: Esta segunda parte del script es la que sí se encarga de llevar a cabo las copias de seguridad en mi equipo local.

#!/usr/bin/env bash
# -*- coding: utf-8 -*-

# Carrega les variables d'entorn que estan en el fitxer backup.env
# En cas d'error donar un missatge
ENV_FILE="$HOME/.local/bin/backup.env"

if [ -f "$ENV_FILE" ]; then
    set -a
    source "$ENV_FILE"
    set +a
else
    echo "Error: No se encuentra el archivo $ENV_FILE"
    exit 1
fi

# Amb els valors del fitxer backup.env, les pasem a variables per fer-les servir més endavant
# Configuración de Restic
export RESTIC_PASSWORD=${RESTIC_PASSWORD}
export AWS_ACCESS_KEY_ID=${SERVER_AWS_ACCESS_KEY_ID}
export AWS_SECRET_ACCESS_KEY=${SERVER_AWS_SECRET_ACCESS_KEY}

# Aqui tenim les ubicacions dels repositoris
# Com veus tinc la del servidor local
# I més endavant anira la del VPS
# Configuración de repositorios
REPOS=(
     "s3:${SERVER_MINIO_URL}/minio_repositori"
)

# Directoris dels que volem copies de seguretat
DIRECTORIOS=(
    "/home/user/.config"
    "/home/user/.fonts"
    "/home/user/.icons"
    "/home/user/.local/bin"
    "/home/user/.ssh"
    "/home/user/.themes"
    "/home/user/.signature"
    "/home/user/.bashrc"
    "/home/user/Mail"
    "/home/user/Projects"
    "/home/user/Varios/Novela"
)

# Aqui informem de els fitxers amb les extensions excloses
EXCLUSIONES=(
    "--exclude=*.tmp"
    "--exclude=*.mkv"
    "--exclude=*.mp4"
    "--exclude=*.mp3"
    "--exclude=*.avi"
    "--exclude=*.log"
    "--exclude=*.AppImage"
)
#
# Ara si que ve la festa
#

# Es realitzar les copies de seguretat a cada repositori
# Una vegada finalitzat, s'enviar notificació
for REPO in "${REPOS[@]}"; do
    create_output=$(restic -r "$REPO" backup \
                    --tag ${TAG_1} \
                    --tag ${TAG_2} \
                    --host ${HOST} \
                    --verbose \
                    --skip-if-unchanged \
                    "${DIRECTORIOS[@]}" \
                    "${EXCLUSIONES[@]}")
    ok=$?
    enviarNotificacions "$REPO" "create" "$create_output" "$ok"
done

# Es realitzar una verificació de la copia de seguretat
# També, una vegada finalitzat el procediment, s'envia una notificació
for REPO in "${REPOS[@]}"; do
    check_output=$(restic -r "$REPO" check)
    ok=$?
    enviarNotificacions "$REPO" "check" "$check_output" "$ok"
done

# S'esborren les copies de seguretat que sobrepassen el limit que em informt
# En aquest cas es el següent:
#  7 diaries
#  4 setmanals
#  6 mensuals
# També s'envia una notificació a la finalització del procediment
for REPO in "${REPOS[@]}"; do
    prune_output=$(restic -r "$REPO" forget \
                    --prune \
                    --keep-daily 7 \
                    --keep-weekly 4 \
                    --keep-monthly 6)
    ok=$?
    enviarNotificacions "$REPO" "prune" "$prune_output" "$ok"
done

# S'obte un llistat de les copies que tenim en cada repositori
# També s'envia una notificació a la finalització del procediment
for REPO in "${REPOS[@]}"; do
    snapshots_output=$(restic -r "$REPO" snapshots -c)
    ok=$?
    enviarNotificacions "$REPO" "snapshots" "$snapshots_output" "$ok"
done

Una de las partes más importantes del proceso para hacer las copias de seguridad ya la tenemos en marcha: el script que realiza las copias de seguridad y las envía a nuestro servidor (S3) de copias de seguridad. Recordad que, en nuestro caso, el servidor que tenemos instalado es MiniO.

Con esto ya podrías dar por finalizado el procedimiento de copias de seguridad. Pero recordando un Docker que había conocido gracias a Lázaro, que no es otro que Backrest, era el encargado de realizar las copias de seguridad de mi servidor local y subirlas a Mega, pero todo se fue 💩 en el momento en que empezaron a fallar los HDD por culpa de la alimentación, así que lo dejé de lado.

Para hacer un breve resumen de lo que es Backrest, es un cliente gráfico de Restic, y si eso era así, podía utilizarlo como cliente de mis copias de seguridad situadas en el servidor local. Lo único que tenía que hacer era informar dónde estaban estas copias y qué tipo de servicio estaba usando (S3).

nota: Con respecto a Backrest, os recomiendo que vayáis a leer el articulo de Carlos M. que tiene en su página web.

Asimismo, si os fijáis, en el script, concretamente en la parte que se encarga de hacer las copias de seguridad, tenemos estas 2 variables u opciones TAG_1 y TAG_2:

  • TAG_1 identifica la copia de seguridad
  • TAG_2 identifica el creador de la copia de seguridad

Esto por sí solo no hace nada, pero a la hora de ir a Backrest, en vez de ver que tal copia pertenece a unsigned, que puede hacer un poco de daño a los ojos 😎, lo tenemos identificado por el TAG_1 y cuando visualizamos la información de las copias vemos el creador de las mismas, que es el TAG_2, quedando de la siguiente manera:

Una vez que tenía esto, todo lo demás es bien sencillo.

Ahora sí que tengo la unión perfecta de los 3 mundos:

  • Restic se encarga de realizar las copias de seguridad de mi equipo local a mi servidor S3
  • MiniO es mi servidor de copias de seguridad (S3)
  • Backrest es mi cliente gráfico para visualizar las copias de seguridad que voy haciendo y así tenerlas controladas

Aquí podría añadir un mundo más, que sería Matrix, que es el encargado de notificarme las acciones que se van haciendo mientras se realiza la copia de seguridad.

Lo único que hay que tener en cuenta con Backrest es lo siguiente:

  • Trabajando de esta manera, cuando nos conectamos a él, no refresca, o yo no he sabido cómo hacerlo, los snapshots, así que solamente tenemos que ir a nuestra sección de repositorios y refrescar el índice de estos y ya nos aparecen las copias de seguridad.
  • En el momento en que queramos recuperar algún archivo, no lo hace contra mi equipo local; no te aparece el fichero y tú lo descargas y listo, sino que lo recupera en el servidor local. Así que, una vez que se ha recuperado, tienes que ir al directorio donde lo ha dejado y moverlo a tu equipo local. Como alternativa, es recuperar desde tu equipo local el archivo que necesitas y entonces sí que funcionará.

Hasta aquí hemos llegado en la segunda parte de este articulo, nos queda la última y no por ello la menos importante.

◇ Referencia