0 Votes

Code source wiki de Sauvegarde

Version 3.1 par john le 2026/09/18 23:25

Masquer les derniers auteurs
john 1.1 1 Sauvegarde quotidienne du serveur principal vers le Raspberry Pi avec [[Plakar>>https://plakar.io]] : dépôt chiffré et dédupliqué, transport SFTP.
2
3 == Fonctionnement ==
4
5 |=Élément|=Valeur
6 |Machine sauvegardée|[[Serveur principal>>Wiki Batcave John.Infrastructure.ServeurPrincipal.WebHome]]
7 |Dépôt|SSD USB du [[Raspberry Pi>>Wiki Batcave John.Infrastructure.RaspberryPi.WebHome]]
8 |Transport|SFTP
9 |Déclenchement|Cron, chaque nuit à 3 h 30
10 |Rétention|30 jours glissants
11 |Script|##/root/backup-plakar.sh##
12 |Journal|##/var/log/backup-plakar.log##, avec rotation par logrotate
13
14 Chaque exécution :
15
16 * exporte toutes les bases en SQL dans ##<APPDATA>/dumps## ;
john 3.1 17 * sauvegarde les données des conteneurs, la bibliothèque Immich et le contenu de Joplin, en excluant les fichiers bruts des bases ;
john 1.1 18 * supprime les instantanés de plus de 30 jours.
19
20 {{info}}
21 Les fichiers bruts d'une base en fonctionnement ne sont pas fiables pour une restauration. Ce sont les dumps SQL qui font foi.
22 {{/info}}
23
24 == Script ==
25
26 {{code language="bash"}}
27 #!/bin/bash
28 set -euo pipefail
29 umask 077 # Ajout : dumps lisibles par root seul
30
31 REPO="sftp://<UTILISATEUR>@<HOTE_DEPOT>:<CHEMIN_DEPOT>"
32 KEYFILE="<FICHIER_PHRASE_SECRETE>"
33 DUMPS="<APPDATA>/dumps"
34 mkdir -p "$DUMPS"
35
36 # Dumps MariaDB/MySQL
37 for c in xwiki-mariadb-db passbolt-db castopod-test-db; do
38 docker exec "$c" sh -c 'exec mysqldump -uroot -p"${MYSQL_ROOT_PASSWORD:-$MARIADB_ROOT_PASSWORD}" --all-databases' \
39 > "$DUMPS/$c.sql" 2>/dev/null \
40 || docker exec "$c" sh -c 'exec mariadb-dump -uroot -p"${MYSQL_ROOT_PASSWORD:-$MARIADB_ROOT_PASSWORD}" --all-databases' \
41 > "$DUMPS/$c.sql" 2>/dev/null \
42 || echo "ATTENTION: dump $c échoué" >&2
43 done
44
45 # Nextcloud : dump via l'utilisateur applicatif
john 2.1 46 docker exec "$(docker ps -q -f name=nextcloud_db)" sh -c 'exec mariadb-dump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE"' \
john 1.1 47 > "$DUMPS/nextcloud.sql" 2>/dev/null \
48 || echo "ATTENTION: dump nextcloud échoué" >&2
49
50 # Dumps PostgreSQL
51 for c in joplin-db flus-db wallabag-db immich_postgres vikunja-db jellystat-db n8n-postgres dawarich_db; do # Ajout : dawarich_db
52 docker exec "$c" sh -c 'exec pg_dumpall -U "$POSTGRES_USER"' \
53 > "$DUMPS/$c.sql" 2>/dev/null \
54 || echo "ATTENTION: dump $c échoué" >&2
55 done
56
57 # Sauvegarde, sans core dumps, binlogs ni fichiers bruts des bases
58 plakar --concurrency 2 -keyfile "$KEYFILE" at "$REPO" backup \
59 -ignore "**/joplin-app/core.*" \
60 -ignore "**/Nextcloud/DB/**" \
61 -ignore "**/log/mysql/**" \
62 -ignore "**/xwiki/mariadb/**" \
63 -ignore "**/store.bak.*/**" \
64 <APPDATA> \
john 3.1 65 <BIBLIOTHEQUE_IMMICH>\
66 <CONTENU_JOPLIN>
john 1.1 67
68 # Rétention : 30 jours glissants
69 plakar -keyfile "$KEYFILE" at "$REPO" rm -before 30d -apply
70 {{/code}}
71
72 Tâche cron, ##/etc/cron.d/backup-plakar## :
73
74 {{code}}
75 30 3 * * * root /root/backup-plakar.sh >> /var/log/backup-plakar.log 2>&1
76 {{/code}}
77
78 == Ajouter une base ==
79
80 Ajouter le nom du conteneur dans la boucle MariaDB ou PostgreSQL du script, puis exclure ses fichiers bruts avec un ##-ignore## s'ils se trouvent dans ##<APPDATA>##.
81
82 == Vérifier ==
83
84 {{code language="bash"}}
85 tail -n 50 /var/log/backup-plakar.log
86 grep ATTENTION /var/log/backup-plakar.log
87 sudo plakar -keyfile <FICHIER_PHRASE_SECRETE> at <REPO> ls
88 {{/code}}
89
90 == Restaurer ==
91
92 Restaurer un instantané complet dans un dossier temporaire :
93
94 {{code language="bash"}}
95 sudo plakar -keyfile <FICHIER_PHRASE_SECRETE> at <REPO> restore -to /tmp/restore <ID_INSTANTANE>
96 {{/code}}
97
98 Réinjecter une base MariaDB :
99
100 {{code language="bash"}}
101 docker exec -i <CONTENEUR> sh -c 'exec mariadb -uroot -p"$MARIADB_ROOT_PASSWORD"' < /tmp/restore/<CHEMIN>/dumps/<CONTENEUR>.sql
102 {{/code}}
103
104 Réinjecter une base PostgreSQL (dump complet de l'instance) :
105
106 {{code language="bash"}}
107 docker exec -i <CONTENEUR> sh -c 'exec psql -U "$POSTGRES_USER" -d postgres' < /tmp/restore/<CHEMIN>/dumps/<CONTENEUR>.sql
108 {{/code}}
109
110 {{warning}}
111 Une sauvegarde qui n'a jamais été restaurée n'est pas une sauvegarde vérifiée. Faire un essai de restauration de temps en temps, dans un dossier temporaire.
112 {{/warning}}
113
114 == Incidents connus ==
115
116 |=Symptôme|=Cause|=Solution
117 |Verrou restant après une exécution interrompue|Le processus a été coupé en cours|Supprimer le verrou orphelin avant de relancer
118 |Avertissements VFS|Cache local incohérent|Vider ##~~/.cache/plakar## de root
119 |Transfert coupé (EOF SFTP) sur de gros fichiers|Lien Wi-Fi du dépôt instable|Économie d'énergie Wi-Fi désactivée sur le Pi ; passer à ##~-~-concurrency 1## pour une première sauvegarde volumineuse
120 |Déconnexion du SSD pendant la sauvegarde|Pont USB en mode UAS|Voir la configuration SSD sur la page [[Raspberry Pi>>Wiki Batcave John.Infrastructure.RaspberryPi.WebHome]]