0 Votes

Modifications pour le document Sauvegarde

Modifié par john le 2026/10/03 20:01

Depuis la version 4.1
modifié par john
sur 2026/09/19 19:19
Commentaire de modification : Il n'y a aucun commentaire pour cette version
À la version 7.2
modifié par john
sur 2026/10/03 20:00
Commentaire de modification : Il n'y a aucun commentaire pour cette version

Résumé

Détails

Propriétés de la Page
Contenu
... ... @@ -1,11 +1,13 @@
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 2  
3 +{{toc/}}
4 +
3 3  == Fonctionnement ==
4 4  
5 5  |=Élément|=Valeur
6 6  |Machine sauvegardée|[[Serveur principal>>Wiki Batcave John.Infrastructure.ServeurPrincipal.WebHome]]
7 7  |Dépôt|SSD USB du [[Raspberry Pi>>Wiki Batcave John.Infrastructure.RaspberryPi.WebHome]]
8 -|Transport|SFTP
10 +|Transport|SFTP, via l'intégration Plakar ##sftp##
9 9  |Déclenchement|Cron, chaque nuit à 3 h 30
10 10  |Rétention|30 jours glissants
11 11  |Script|##/root/backup-plakar.sh##
... ... @@ -14,15 +14,52 @@
14 14  Chaque exécution :
15 15  
16 16  * exporte toutes les bases en SQL dans ##<APPDATA>/dumps## ;
17 -* sauvegarde les données des conteneurs, la bibliothèque Immich et le contenu de Joplin, en excluant les fichiers bruts des bases ;
19 +* attend la fin de la sauvegarde Borg de [[Nextcloud>>Wiki Batcave John.Infrastructure.ServeurPrincipal.Nextcloud.WebHome]] AIO (planifiée à 3 h 00), au plus une heure ;
20 +* sauvegarde les données des conteneurs, la bibliothèque Immich, le contenu de Joplin et le dépôt Borg de Nextcloud AIO, en excluant les fichiers bruts des bases et les données brutes de Nextcloud ;
18 18  * supprime les instantanés de plus de 30 jours.
19 19  
20 20  {{info}}
21 21  Les fichiers bruts d'une base en fonctionnement ne sont pas fiables pour une restauration. Ce sont les dumps SQL qui font foi.
25 +
26 +Nextcloud AIO fait exception : il n'y a pas de dump, sa base, ses fichiers et sa configuration sont dans son propre dépôt Borg, cohérent car produit conteneurs arrêtés. Plakar copie ce dépôt tel quel, d'où l'attente de la fin de la sauvegarde Borg : copier un dépôt en cours d'écriture donnerait une copie incohérente.
22 22  {{/info}}
23 23  
24 -== Mise en place du dépôt ==
29 +{{info}}
30 +Les dumps sont faits avec ##docker exec##, donc avec le client ##pg_dump## ou ##mysqldump## du conteneur lui-même, toujours à la bonne version. Les intégrations Plakar ##postgresql## et ##mysql## ont été écartées : elles exigent un accès TCP à chaque base et des clients de même version installés sur l'hôte, et produisent un instantané séparé par base.
31 +{{/info}}
25 25  
33 +== Mise en place ==
34 +
35 +=== Installer Plakar (les deux machines) ===
36 +
37 +Installer le paquet ##plakar## (paquet ##.deb## disponible sur la [[page de téléchargement>>https://www.plakar.io/download]]) sur le serveur principal et sur le Raspberry Pi, **dans la même version**.
38 +
39 +{{code language="bash"}}
40 +sudo apt install ./plakar_<VERSION>_<ARCH>.deb
41 +plakar version
42 +{{/code}}
43 +
44 +=== Installer l'intégration SFTP (serveur principal) ===
45 +
46 +Depuis Plakar 1.1, le transport SFTP n'est plus inclus dans le binaire : c'est une intégration à installer à part. Sans elle, toute commande sur un dépôt ##sftp:~/~/## échoue.
47 +
48 +Les intégrations sont installées **par utilisateur** (dans ##~~/.local/share/plakar/plugins##). La sauvegarde tournant en root, l'installation se fait avec ##sudo##.
49 +
50 +Le téléchargement des intégrations précompilées demande un compte Plakar connecté (gratuit). Le serveur n'ayant pas de navigateur, utiliser ##-no-spawn## : Plakar affiche une URL à ouvrir sur un autre poste, puis un code à saisir dans le terminal.
51 +
52 +{{code language="bash"}}
53 +sudo plakar login -github -no-spawn # ou : sudo plakar login -email <ADRESSE>
54 +sudo plakar login -status
55 +sudo plakar pkg add sftp
56 +sudo plakar pkg list
57 +{{/code}}
58 +
59 +{{info}}
60 +La connexion au compte ne sert qu'au gestionnaire d'intégrations. Les sauvegardes et restaurations n'en dépendent pas.
61 +
62 +Le Raspberry Pi n'a pas besoin de l'intégration : il ouvre le dépôt en local.
63 +{{/info}}
64 +
26 26  === Sur le Raspberry Pi (dépôt) ===
27 27  
28 28  Utilisateur dédié, sans shell :
... ... @@ -38,17 +38,19 @@
38 38  
39 39  {{code}}
40 40  Match User plakar
41 - ForceCommand internal-sftp
80 + ForceCommand internal-sftp -l VERBOSE
42 42   AllowTcpForwarding no
43 43   X11Forwarding no
44 44  {{/code}}
45 45  
46 46  {{code language="bash"}}
47 -sudo systemctl reload ssh
86 +sudo sshd -t && sudo systemctl reload ssh
48 48  {{/code}}
49 49  
50 50  Même en cas de vol de la clé, elle ne donne ni shell ni tunnel : seulement un accès SFTP.
51 51  
91 +L'option ##-l VERBOSE## journalise chaque opération SFTP (ouverture, renommage, suppression, refus) dans ##journalctl -u ssh##. Sans elle, un refus côté dépôt n'apparaît nulle part sur le Pi.
92 +
52 52  === Sur le serveur principal (source) ===
53 53  
54 54  Clé SSH dédiée, sans phrase de passe puisqu'elle sert à la tâche cron :
... ... @@ -88,9 +88,30 @@
88 88  Le dépôt est chiffré avec cette phrase secrète. Sans elle, les sauvegardes sont illisibles, même pour leur propriétaire : en conserver une copie dans le gestionnaire de mots de passe, jamais uniquement sur le serveur.
89 89  {{/warning}}
90 90  
132 +== Mettre à jour Plakar ==
133 +
134 +Le paquet ##plakar## et l'intégration ##sftp## se mettent à jour **séparément** : ##apt## ne touche pas aux intégrations. Après chaque mise à jour du paquet :
135 +
136 +{{code language="bash"}}
137 +# Sur les deux machines : même version partout
138 +plakar version
139 +
140 +# Sur le serveur principal : mise à jour de toutes les intégrations de root
141 +sudo plakar login -status # se reconnecter si besoin
142 +sudo plakar pkg add -u
143 +sudo plakar pkg list
144 +
145 +# Contrôle de l'accès au dépôt
146 +sudo plakar -keyfile <FICHIER_PHRASE_SECRETE> at <REPO> ls | head -2
147 +{{/code}}
148 +
149 +{{warning}}
150 +Une intégration restée sur une ancienne version alors que Plakar a été mis à jour peut provoquer des échecs difficiles à diagnostiquer, sur le verrou du dépôt notamment (voir Incidents connus). Ne jamais mettre à jour le paquet sans mettre à jour l'intégration dans la foulée.
151 +{{/warning}}
152 +
91 91  == Restaurer si le serveur principal est perdu ==
92 92  
93 -Le dépôt peut s'ouvrir directement sur le Raspberry Pi, où Plakar est aussi installé, avec la phrase secrète récupérée dans le gestionnaire de mots de passe :
155 +Le dépôt peut s'ouvrir directement sur le Raspberry Pi, où Plakar est aussi installé, avec la phrase secrète récupérée dans le gestionnaire de mots de passe. L'accès étant local, aucune intégration ni compte Plakar n'est nécessaire :
94 94  
95 95  {{code language="bash"}}
96 96  sudo plakar at <CHEMIN_DEPOT> ls
... ... @@ -104,8 +104,17 @@
104 104  {{code language="bash"}}
105 105  #!/bin/bash
106 106  set -euo pipefail
107 -umask 077 # Ajout : dumps lisibles par root seul
169 +umask 077
108 108  
171 +# Alertes Telegram
172 +. /root/.backup-telegram
173 +notifier() {
174 + curl -fsS -m 10 "https://api.telegram.org/bot$TG_TOKEN/sendMessage" \
175 + -d chat_id="$TG_CHAT" --data-urlencode text="$1" >/dev/null || true
176 +}
177 +attention() { echo "ATTENTION: $1" >&2; notifier "⚠️ Sauvegarde : $1"; }
178 +trap 'notifier "❌ Sauvegarde interrompue à la ligne $LINENO"' ERR
179 +
109 109  REPO="sftp://<UTILISATEUR>@<HOTE_DEPOT>:<CHEMIN_DEPOT>"
110 110  KEYFILE="<FICHIER_PHRASE_SECRETE>"
111 111  DUMPS="<APPDATA>/dumps"
... ... @@ -117,34 +117,43 @@
117 117   > "$DUMPS/$c.sql" 2>/dev/null \
118 118   || docker exec "$c" sh -c 'exec mariadb-dump -uroot -p"${MYSQL_ROOT_PASSWORD:-$MARIADB_ROOT_PASSWORD}" --all-databases' \
119 119   > "$DUMPS/$c.sql" 2>/dev/null \
120 - || echo "ATTENTION: dump $c échoué" >&2
191 + || attention "dump $c échoué"
121 121  done
122 122  
123 -# Nextcloud : dump via l'utilisateur applicatif
124 -docker exec "$(docker ps -q -f name=nextcloud_db)" sh -c 'exec mariadb-dump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE"' \
125 - > "$DUMPS/nextcloud.sql" 2>/dev/null \
126 - || echo "ATTENTION: dump nextcloud échoué" >&2
127 -
128 128  # Dumps PostgreSQL
129 -for c in joplin-db flus-db wallabag-db immich_postgres vikunja-db jellystat-db n8n-postgres dawarich_db; do # Ajout : dawarich_db
195 +for c in joplin-db flus-db wallabag-db immich_postgres vikunja-db jellystat-db n8n-postgres dawarich_db; do
130 130   docker exec "$c" sh -c 'exec pg_dumpall -U "$POSTGRES_USER"' \
131 131   > "$DUMPS/$c.sql" 2>/dev/null \
132 - || echo "ATTENTION: dump $c échoué" >&2
198 + || attention "dump $c échoué"
133 133  done
134 134  
135 -# Sauvegarde, sans core dumps, binlogs ni fichiers bruts des bases
201 +# Attente de la fin de la sauvegarde Borg d'AIO (planifiée à 3h00)
202 +attente=0
203 +while docker ps --format '{{.Names}}' | grep -qx nextcloud-aio-borgbackup; do
204 + if [ "$attente" -ge 3600 ]; then
205 + attention "Borg AIO encore en cours après 1 h : dépôt Borg possiblement incohérent"
206 + break
207 + fi
208 + sleep 60
209 + attente=$((attente + 60))
210 +done
211 +
212 +# Backup avec exclusions : core dumps, binlogs, fichiers bruts des bases
213 +# et données brutes de Nextcloud AIO (déjà dans le dépôt Borg, de façon cohérente)
136 136  plakar --concurrency 2 -keyfile "$KEYFILE" at "$REPO" backup \
137 137   -ignore "**/joplin-app/core.*" \
138 - -ignore "**/Nextcloud/DB/**" \
216 + -ignore "**/Nextcloud-AIO/data/**" \
139 139   -ignore "**/log/mysql/**" \
140 140   -ignore "**/xwiki/mariadb/**" \
141 141   -ignore "**/store.bak.*/**" \
142 142   <APPDATA> \
143 - <BIBLIOTHEQUE_IMMICH>\
144 - <CONTENU_JOPLIN>
221 + <BIBLIOTHEQUE_IMMICH> \
222 + <CONTENU_JOPLIN> \
223 + <DEPOT_BORG_AIO>
145 145  
146 146  # Rétention : 30 jours glissants
147 147  plakar -keyfile "$KEYFILE" at "$REPO" rm -before 30d -apply
227 +notifier "✅ Sauvegarde terminée"
148 148  {{/code}}
149 149  
150 150  Tâche cron, ##/etc/cron.d/backup-plakar## :
... ... @@ -153,6 +153,29 @@
153 153  30 3 * * * root /root/backup-plakar.sh >> /var/log/backup-plakar.log 2>&1
154 154  {{/code}}
155 155  
236 +== Alertes ==
237 +
238 +Le script envoie un message Telegram à chaque exécution :
239 +
240 +|=Message|=Signification
241 +|✅ Sauvegarde terminée|Tout s'est bien passé
242 +|⚠️ Sauvegarde : dump … échoué|Un dump de base a échoué, la sauvegarde a continué sans lui
243 +|⚠️ Sauvegarde : Borg AIO encore en cours après 1 h …|La sauvegarde Borg de Nextcloud n'était pas finie : la copie du dépôt Borg de cette nuit peut être incohérente, celle des nuits précédentes reste utilisable
244 +|❌ Sauvegarde interrompue à la ligne …|Erreur bloquante, la sauvegarde n'a pas eu lieu (la ligne du ##plakar backup## indique un échec de Plakar lui-même : consulter la fin du journal)
245 +
246 +Si aucun message n'arrive un matin, le script n'a pas démarré (serveur éteint, tâche cron cassée).
247 +
248 +Jeton du bot et identifiant du groupe dans ##/root/.backup-telegram##, lisible par root seul :
249 +
250 +{{code language="bash"}}
251 +TG_TOKEN="<JETON_BOT>"
252 +TG_CHAT="<ID_GROUPE>"
253 +{{/code}}
254 +
255 +{{warning}}
256 +Dans le script, chaque ligne continuée doit se terminer par ##\## sans rien après, pas même un espace. Une barre oblique inverse suivie d'un espace ne continue plus la ligne : c'est ce qui a interrompu plusieurs sauvegardes en septembre 2026. Contrôle après toute modification : ##sudo bash -n /root/backup-plakar.sh##, et ##cat -A## pour voir les caractères invisibles en fin de ligne.
257 +{{/warning}}
258 +
156 156  == Ajouter une base ==
157 157  
158 158  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>##.
... ... @@ -162,9 +162,21 @@
162 162  {{code language="bash"}}
163 163  tail -n 50 /var/log/backup-plakar.log
164 164  grep ATTENTION /var/log/backup-plakar.log
268 +sudo grep -nE '^(warn|error|plakar):' /var/log/backup-plakar.log | tail -n 20
165 165  sudo plakar -keyfile <FICHIER_PHRASE_SECRETE> at <REPO> ls
270 +sudo plakar pkg list
166 166  {{/code}}
167 167  
273 +La colonne durée de ##ls## donne le temps de chaque sauvegarde : une hausse brutale mérite un coup d'œil au journal.
274 +
275 +Contrôle d'intégrité du dernier instantané, à lancer **sur le Raspberry Pi** (lecture locale du SSD, sans passer par le réseau) :
276 +
277 +{{code language="bash"}}
278 +sudo -u plakar plakar at <CHEMIN_DEPOT> check <ID_INSTANTANE>
279 +{{/code}}
280 +
281 +Sans identifiant, ##check## vérifie tous les instantanés : c'est très long sur un Pi et doit être terminé avant 3 h 30.
282 +
168 168  == Restaurer ==
169 169  
170 170  Restaurer un instantané complet dans un dossier temporaire :
... ... @@ -185,6 +185,8 @@
185 185  docker exec -i <CONTENEUR> sh -c 'exec psql -U "$POSTGRES_USER" -d postgres' < /tmp/restore/<CHEMIN>/dumps/<CONTENEUR>.sql
186 186  {{/code}}
187 187  
303 +Restaurer Nextcloud AIO : restaurer le dossier ##<DEPOT_BORG_AIO>## sur l'hôte, déployer le mastercontainer sur une installation neuve, puis choisir la restauration dans l'interface AIO (chemin du dépôt, mot de passe Borg, archive). Voir la page [[Nextcloud>>Wiki Batcave John.Infrastructure.ServeurPrincipal.Nextcloud.WebHome]].
304 +
188 188  {{warning}}
189 189  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.
190 190  {{/warning}}
... ... @@ -192,7 +192,9 @@
192 192  == Incidents connus ==
193 193  
194 194  |=Symptôme|=Cause|=Solution
195 -|Verrou restant après une exécution interrompue|Le processus a été coupé en cours|Supprimer le verrou orphelin avant de relancer
312 +|Verrou restant après une exécution interrompue|Le processus a été coupé en cours|Vérifier qu'aucun Plakar ne tourne (##pgrep -a plakar##), puis supprimer le fichier signalé dans ##<CHEMIN_DEPOT>/locks/## sur le Pi
196 196  |Avertissements VFS|Cache local incohérent|Vider ##~~/.cache/plakar## de root
197 197  |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
198 198  |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]]
316 +|Arrêt après une dizaine de minutes, ##failed to refresh the repository lock: sftp: "Failure" (SSH_FX_FAILURE)## répété dans le journal, puis ##lock refresher: failed to refresh the repository lock##|Cause probable : intégration ##sftp## restée sur une ancienne version après une mise à jour de Plakar (octobre 2026). Le verrou est rafraîchi toutes les 5 minutes, les sauvegardes courtes peuvent donc masquer le problème|##sudo plakar pkg add -u##, supprimer le verrou orphelin, consulter ##journalctl -u ssh## sur le Pi (log ##VERBOSE##)
317 +|##authentication required. Run `plakar login`## lors d'un ##pkg add##|Le gestionnaire d'intégrations exige un compte connecté|##sudo plakar login -github -no-spawn##