[UPDATE 2026] Backup total d’un serveur dédié Docker avec rsnapshot — bases de données, volumes et restauration

Published by David on






Backup total d’un serveur dédié avec rsnapshot — support Docker Compose, MySQL, PostgreSQL et SQLite

Backup total d’un serveur dédié avec rsnapshot

Sauvegardes incrémentales avec rsnapshot : bases de données Docker
(MariaDB, MySQL, PostgreSQL, SQLite), volumes, fichiers applicatifs
et configuration MyVestaCP. Serveur de backup dédié ou NAS Synology.

Paramètres à personnaliser

Remplacez chaque {{VARIABLE}} par vos propres valeurs avant d'utiliser ce guide.

Variable Description Exemple
{{IP_NOUVEAU}} IP du serveur principal 198.51.100.20
{{IP_VPS}} IP du VPS secondaire 203.0.113.50
{{HOSTNAME_NOUVEAU}} Hostname serveur principal ns7654321
{{HOSTNAME_VPS}} Hostname du VPS vps-abc12345
{{PORT_SSH_NOUVEAU}} Port SSH serveur principal 22222
{{PORT_SSH_VPS}} Port SSH du VPS 22223
{{DB_PASSWORD}} Mot de passe MariaDB S3cur3P@ss!
{{DOMAINE_GAMING}} Domaine gaming (email) exemple-gaming.fr
{{DOMAINE_SITE}} Domaine du site web monsite.fr
{{INSTANCE_1}} Instance Odoo 17 principale moninstance
{{INSTANCE_2}} Instance Odoo 17 secondaire autreinstance
{{DB_ODOO8}} Base Odoo 8 mabase-odoo
{{DB_PRESTASHOP}} Base PrestaShop prestashop_monsite
{{USER_VESTA}} Utilisateur MyVestaCP admin

Sommaire

  1. Pourquoi rsnapshot ?
  2. Architecture et prérequis
  3. Préparer le serveur de données
  4. Scripts de dump des bases de données Docker
  5. Script de pré-backup Docker
  6. Préparer le serveur de backup
  7. Configurer rsnapshot
  8. Automatiser avec cron
  9. Tester et valider
  10. Restauration
  11. Variante Synology (Container Manager)

1) Pourquoi rsnapshot ?

rsnapshot est un outil basé sur rsync qui crée des sauvegardes
incrémentales par snapshots
. Les fichiers inchangés ne sont pas dupliqués :
ils sont reliés par des hard links, ce qui économise
considérablement l’espace disque tout en gardant plusieurs versions complètes du serveur.

Chaque snapshot est un répertoire autonome : on peut y naviguer, copier des fichiers,
ou restaurer un serveur complet sans outil spécial.

Docker change tout. Sur un serveur classique, rsnapshot peut copier
directement /var/lib/mysql/ ou /var/lib/postgresql/.
Avec Docker, les bases de données tournent dans des conteneurs isolés :
il faut les dumper via docker exec avant de les sauvegarder.
Copier un volume Docker pendant que le conteneur écrit dedans peut produire un
backup corrompu.


2) Architecture et prérequis

2.1 Schéma global

2.2 Inventaire des services Docker

Service Base de données Conteneur BDD Données
Pterodactyl MariaDB 10.11 pterodactyl-db Panel + 6 serveurs CS 1.6
TeamSpeak 3 SQLite teamspeak3-server 235 Go (fichiers, icônes, avatars)
Akeneo PIM 7 MySQL 8.0.30 + Elasticsearch akeneo-mysql, akeneo-es Code PIM + indices ES
ownCloud 10 PostgreSQL 13 owncloud-db 568 Go (fichiers utilisateurs)
Odoo 17 (x4) PostgreSQL 13 odoo17-db Filestore + modules custom
Odoo 8 PostgreSQL 9.6 odoo8-db Filestore + modules custom
EmuLinker Config + JAR (< 100 Mo)
ZNC Config files znc-server 2,4 Go (logs IRC)
Sites web MyVestaCP MySQL natif Service mysql système PrestaShop, WordPress, Matomo, etc.
LGSL (monitoring) Fichiers PHP dans /home/{{USER_VESTA}}/web/

LGSL (Live Game Server List) est un panel de monitoring des serveurs de jeu.
Ses fichiers sont dans /home/{{USER_VESTA}}/web/ et sont sauvegardés
automatiquement par rsnapshot via la copie du / complet.
Pas de base de données à dumper — tout est en fichiers plats et cache.

2.3 Prérequis

  • Serveur de données : Debian 12, Docker, docker compose, bzip2
  • Serveur de backup : rsnapshot, rsync, SSH, disque externe ext4 (≥ 2 To recommandé)
  • Connectivité : SSH par clé entre backup → données

3) Préparer le serveur de données

3.1 Installer les paquets

3.2 Créer l’utilisateur de backup

3.3 Script wrapper rsync (exécution root)

rsnapshot doit pouvoir lire tous les fichiers du serveur.
Le wrapper permet à backup_user d’exécuter rsync en root
via sudo, sans ouvrir un accès root SSH direct.

Coller :

3.4 Droits sudo

Ajouter à la fin :

Pourquoi sudo docker ? Les scripts de dump utilisent
docker exec pour accéder aux bases de données dans les conteneurs.
Sans cette ligne, backup_user ne pourrait pas dumper les bases.

3.5 Clé SSH

La clé SSH est générée sur le serveur de backup et copiée
vers le serveur de données. Voir section 6.

3.6 Rendre les scripts exécutables


4) Scripts de dump des bases de données Docker

Chaque type de base de données a son propre script de dump.
Les dumps sont stockés dans /home/backup_user/files/
et seront récupérés par rsnapshot via rsync.

Différence avec un serveur classique : on n’utilise plus
mysqldump ou pg_dump directement.
Tout passe par sudo docker exec car les bases
tournent dans des conteneurs isolés.

4.1 Dump MariaDB / MySQL (Pterodactyl, Akeneo)

Coller :

--single-transaction permet de dumper sans verrouiller
les tables (InnoDB). Les conteneurs restent accessibles pendant le dump.

Elasticsearch : le snapshot ES est optionnel. Si le conteneur ES
n’est pas accessible ou si le nom diffère, le script affiche un warning
et continue. Les indices Akeneo peuvent toujours être recréés manuellement
avec bin/console akeneo:elasticsearch:reset-indexes (plus lent mais fonctionnel).

4.2 Dump PostgreSQL (ownCloud, Odoo 17, Odoo 8)

Coller :

4.3 Backup SQLite (TeamSpeak 3)

Coller :

Pas d’arrêt nécessaire : on copie la DB SQLite + ses fichiers
WAL (Write-Ahead Log) et SHM directement depuis le conteneur.
SQLite rejouera le WAL à l’ouverture pour garantir la cohérence des données.
Les utilisateurs ne sont pas déconnectés.

Pourquoi pas sqlite3 .backup ?
Le conteneur TeamSpeak officiel n’inclut pas l’utilitaire sqlite3.
La copie directe DB + WAL + SHM est une alternative fiable qui produit
un backup cohérent sans nécessiter d’outils supplémentaires.

Pourquoi ne pas backuper les 235 Go de fichiers TS ici ?
Les fichiers TeamSpeak (icônes, avatars, fichiers de channels) sont
en bind mount dans /home/docker/teamspeak3/data/.
Rsnapshot les copiera directement via rsync (section 7), pas besoin
de les archiver dans ce script.

4.4 Dump MySQL natif (MyVestaCP — PrestaShop, WordPress, Matomo…)

Ne pas confondre avec les bases Docker. MyVestaCP gère ses propres bases MySQL
(créées via le panel DB) qui tournent directement sur le système, pas dans un conteneur.
Si tu as des sites PrestaShop, WordPress, Matomo, etc. hébergés via VestaCP,
leurs bases sont natives et nécessitent un dump séparé.

Coller :

Créer le fichier de credentials MySQL :

Coller :

Où trouver le mot de passe root MySQL ?
Sur un serveur MyVestaCP / HestiaCP, le mot de passe root MySQL est stocké dans :
/usr/local/vesta/conf/mysql.conf (MyVestaCP) ou
/usr/local/hestia/conf/mysql.conf (HestiaCP).
Afficher avec : cat /usr/local/vesta/conf/mysql.conf

Pourquoi un fichier de credentials ? Passer le mot de passe avec -p
sur la ligne de commande affiche un warning MySQL et le mot de passe apparaît dans
ps aux. Le fichier --defaults-extra-file est la méthode
recommandée par MySQL.

4.5 Rendre les scripts exécutables


5) Script de pré-backup Docker

Ce script orchestre tous les dumps dans l’ordre.
Il est appelé par rsnapshot (via SSH) avant la copie des fichiers.

Coller :

Ordre d’exécution : MySQL, PostgreSQL et SQLite peuvent tourner en parallèle
(conteneurs indépendants). Aucun arrêt de service n’est nécessaire grâce
à --single-transaction (MySQL/PG) et la copie directe DB+WAL (TS3).

5.1 Tester chaque script individuellement

Indispensable : tester chaque script un par un sur le serveur de données
avant de passer à la configuration du serveur de backup. Un dump vide (20 octets)
ou une erreur silencieuse ici = un backup inutile découvert trop tard.

Test 1 — MySQL / MariaDB Docker

Vérifier :

Erreurs fréquentes :
Error: No such container → vérifier le nom exact avec sudo docker ps --format "{{.Names}}".
Access denied → vérifier le mot de passe root dans le docker-compose.yml
(MYSQL_ROOT_PASSWORD).

Test 2 — PostgreSQL Docker

Vérifier :

Erreur fréquente :
FATAL: role "xxx" does not exist → vérifier le user PostgreSQL dans le
docker-compose.yml (POSTGRES_USER).
Pour trouver le bon user : sudo docker exec owncloud-db psql -U postgres -c "\du"

Test 3 — SQLite TeamSpeak

Vérifier :

Vérification : l’archive doit contenir ts3server.sqlitedb (~4 Mo),
ts3server.sqlitedb-wal, ts3server.sqlitedb-shm et licensekey.dat.
Si la DB ne fait que quelques octets, vérifiez que le conteneur teamspeak3-server tourne.

Test 4 — MySQL natif (MyVestaCP)

Vérifier :

Erreur fréquente :
ERROR 1045 (28000): Access denied → le fichier
/etc/mysql/backup-credentials.cnf n’existe pas ou contient un mauvais mot de passe.
Trouver le mot de passe root : cat /usr/local/vesta/conf/mysql.conf

Test 5 — Script complet (pré-backup)

Une fois que les 4 scripts passent individuellement :

Le log doit afficher exit 0 pour chaque script :

Ne pas passer à la section suivante tant que tous les scripts ne retournent pas
exit 0 et que les dumps ne font pas une taille cohérente.


6) Préparer le serveur de backup

6.1 Installer les paquets

6.2 Préparer le disque de backup

Espace requis : avec ownCloud (568 Go) + TeamSpeak (235 Go) + le reste,
le serveur fait environ 835 Go de données. Avec la rétention
(7 daily + 4 weekly + 3 monthly) et les hard links, prévoir un
disque de 2 To minimum.

6.3 Créer l’utilisateur de backup

Ajouter dans /etc/sudoers via visudo :

6.4 Générer et copier la clé SSH

Option A : depuis le serveur de backup (Linux)

Option B : depuis Windows (PowerShell)

Si tu gères ton serveur depuis Windows (pas d’accès SSH direct),
tu peux générer la clé en PowerShell et la déployer via SFTP.

Cela crée deux fichiers dans C:\Users\\.ssh\ :

  • id_ed25519_rsnapshot — clé privée
  • id_ed25519_rsnapshot.pub — clé publique

Ensuite :

  1. Ouvrir id_ed25519_rsnapshot.pub avec un éditeur de texte et copier son contenu
  2. Sur chaque serveur de données, ajouter ce contenu à la fin de
    /home/backup_user/.ssh/authorized_keys (via SFTP ou le panel web) —
    la même clé publique peut être autorisée sur plusieurs serveurs
  3. Sur le NAS Synology, déposer la clé privée
    id_ed25519_rsnapshot dans /volume1/NetBackup/.ssh/
  4. Sécuriser les permissions sur le NAS :

Tester chaque connexion depuis le NAS :

6.5 Tester rsync à distance

6.6 Script wrapper rsnapshot

Coller :


7) Configurer rsnapshot

Tabulations obligatoires : dans rsnapshot.conf,
les séparateurs entre les champs sont des tabulations (pas des espaces).
Une erreur fréquente est d’utiliser des espaces — rsnapshot refusera de démarrer.

7.1 Fichier d’exclusions

Coller :

Pourquoi exclure /var/lib/docker/overlay2/ ?
Ce répertoire contient les couches d’images Docker
(plusieurs dizaines de Go). Elles sont téléchargeables depuis les registres
(Docker Hub, ghcr.io). Les données applicatives
sont dans les volumes (/var/lib/docker/volumes/)
et les bind mounts (/home/docker/*/),
qui eux sont bien sauvegardés.

7.2 Gestion de plusieurs serveurs avec des ports SSH différents

Dès que l’on sauvegarde plusieurs serveurs ayant des ports SSH différents,
le paramètre global ssh_args de rsnapshot ne peut pas convenir à tous les serveurs
à la fois. Deux approches propres existent :

Approche recommandée : fichier ~/.ssh/config avec des alias

On crée un fichier ~/.ssh/config (sur le serveur de backup) qui définit
un alias par serveur. rsnapshot utilise ensuite ces alias — plus besoin
d’indiquer l’IP ni le port dans rsnapshot.conf.

Coller :

Tester les alias :

Approche alternative : ssh_args par ligne backup

Si l’on ne peut pas (ou ne veut pas) créer un fichier SSH config
(cas Synology avec Docker), on peut surcharger ssh_args
directement sur chaque ligne backup :

Important : les arguments per-ligne ssh_args= sur une ligne
backup remplacent complètement le ssh_args global.
Il faut donc répéter l’argument -i (clé) ET -p (port)
sur chaque ligne. Le ssh_args global ne sert alors qu’à définir
un défaut pour les connexions qui n’ont pas de surcharge.

7.3 Configuration principale (serveur de backup Linux)

Rappel : chaque «TAB» ci-dessous représente
une vraie tabulation. Ne pas remplacer par des espaces.

Tout en une seule ligne backup :
la ligne backup ... :/ copie tout le serveur
sauf les exclusions. Cela inclut automatiquement :

  • /home/docker/*/ — tous les docker-compose.yml, configs, bind mounts
  • /home/backup_user/files/ — les dumps SQL générés par le pré-backup
  • /home/{{USER_VESTA}}/web/ — les sites MyVestaCP (PrestaShop, WordPress, Matomo)
  • /usr/local/vesta/ — la config VestaCP (templates Nginx, crons, users)
  • /var/lib/docker/volumes/ — les volumes Docker nommés (BDD, Redis, etc.)
  • /etc/ — configuration système, SSH, firewall

7.4 Vérifier la configuration


8) Automatiser avec cron

Ajouter :

Pas de hourly : avec 835 Go de données
(ownCloud 568 Go + TeamSpeak 235 Go), un backup toutes les 4 heures serait trop lourd.
Un backup daily à 3h du matin suffit pour la plupart des usages.
Ajouter hourly uniquement si le serveur de backup et la bande passante le permettent.

8.1 Notifications email (optionnel)

ssmtp est obsolète (plus maintenu, retiré de Debian 12).
Utiliser msmtp à la place, qui est compatible en remplacement direct.

Configurer /etc/msmtprc :

Modifier le cron pour envoyer un rapport :

8.2 Limiter la bande passante (optionnel)

Si le serveur de backup est distant et la bande passante limitée,
ajouter dans rsnapshot.conf :

--bwlimit=10MiB limite le transfert à 10 Mo/s.
Ajuster selon la bande passante disponible.


9) Tester et valider

9.1 Tester les scripts de dump sur le serveur de données

9.2 Vérifier l’intégrité des dumps

9.3 Lancer un premier backup complet

Premier backup = copie complète.
Le premier daily va transférer la totalité des données (~835 Go).
Selon la bande passante, cela peut prendre plusieurs heures.
Les backups suivants seront incrémentaux et beaucoup plus rapides.


10) Restauration

Chaque snapshot rsnapshot est un répertoire autonome.
La restauration dépend de ce qu’on veut récupérer.

10.1 Restaurer un fichier ou répertoire

10.2 Restaurer une base de données Docker

MariaDB (Pterodactyl)

MySQL (Akeneo PIM)

MySQL natif (PrestaShop, WordPress, Matomo…)

PostgreSQL (ownCloud)

PostgreSQL (Odoo 17)

PostgreSQL (Odoo 8)

SQLite (TeamSpeak 3)

10.3 Restauration complète d’un service Docker

Pour restaurer un service Docker complet (ex: Pterodactyl après un crash) :

  1. Installer Docker et docker compose sur le nouveau serveur
  2. Restaurer le répertoire complet :
  3. Restaurer les volumes Docker nommés si utilisés :
  4. Démarrer la stack :
  5. Ou restaurer la base depuis le dump SQL (plus fiable) :

Dumps SQL vs volumes bruts : pour les bases de données,
privilégier toujours la restauration via dump SQL
(méthode 5) plutôt que la copie des fichiers bruts du volume
(méthode 3). Les fichiers bruts peuvent être incohérents si le conteneur
écrivait au moment du snapshot rsnapshot.

10.4 Restauration complète du serveur

En cas de perte totale du serveur :

  1. Réinstaller Debian 12 + MyVestaCP
  2. Installer Docker et docker compose
  3. Restaurer /etc/ (SSH, firewall, crons)
  4. Restaurer /usr/local/vesta/ (templates Nginx, config MyVestaCP)
  5. Restaurer /home/{{USER_VESTA}}/web/ (sites web)
  6. Restaurer /home/docker/ (tous les docker-compose.yml et bind mounts)
  7. Restaurer les volumes Docker nommés depuis /var/lib/docker/volumes/
  8. Démarrer chaque stack Docker et injecter les dumps SQL
  9. Vérifier les crons, les templates Nginx, les certificats SSL

11) Variante Synology (Container Manager)

Si le serveur de backup est un NAS Synology, on peut exécuter rsnapshot
via Container Manager (Docker) avec l’image linuxserver/rsnapshot.

11.1 Préparer les répertoires

11.2 Générer et déployer la clé SSH

Générer la clé depuis Windows (PowerShell) ou directement sur le NAS via SSH :

Copier les deux fichiers dans /volume1/NetBackup/.ssh/ sur le NAS :

  • id_ed25519_rsnapshot — clé privée (rester confidentiel)
  • id_ed25519_rsnapshot.pub — clé publique

Sécuriser les permissions sur le NAS (via SSH ou le panneau DSM) :

Ajouter le contenu de id_ed25519_rsnapshot.pub dans
/home/backup_user/.ssh/authorized_keys sur chaque
serveur de données (la même clé publique peut être utilisée pour plusieurs serveurs).

Pourquoi un seul fichier de clé pour plusieurs serveurs ?
La clé SSH identifie le client (le NAS). Chaque serveur de données décide
indépendamment d’autoriser ou non cette clé dans son fichier
authorized_keys. Une seule paire de clés suffit pour n’importe
quel nombre de serveurs.

11.3 Gestion multi-serveurs : ports SSH différents sur Synology

Le NAS Synology exécute rsnapshot dans un conteneur Docker (linuxserver/rsnapshot),
ce qui rend difficile l’utilisation d’un fichier ~/.ssh/config
traditionnel avec des alias. La solution la plus fiable est d’utiliser des
arguments ssh_args par ligne backup pour surcharger le port
serveur par serveur.

Erreur courante : définir un ssh_args global avec
un port ne fonctionne que si tous vos serveurs utilisent le même port SSH.
Dès que vous avez deux serveurs avec des ports différents (ex: {{PORT_SSH_NOUVEAU}} et {{PORT_SSH_VPS}}),
le ssh_args global sera forcément faux pour l’un d’eux.
Il faut supprimer le port du ssh_args global et l’indiquer
sur chaque ligne backup et backup_script.

11.4 Configuration rsnapshot pour Synology (multi-serveurs)

Coller (attention : séparateurs = tabulations, pas des espaces) :

Pourquoi ssh_args sur chaque ligne backup ?
rsnapshot ne supporte qu’un seul ssh_args global.
La syntaxe ssh_args=... dans les options par ligne (4e champ d’une directive
backup) permet de le surcharger pour chaque serveur séparément.
Sans cette surcharge, rsnapshot utiliserait le ssh_args global
— qui ne contient pas le bon port — et la connexion échouerait silencieusement
ou se connecterait sur le mauvais port.

backup_script et les ports : la directive
backup_script exécute une commande shell libre.
Elle ne bénéficie pas du mécanisme de surcharge ssh_args.
Il faut donc indiquer explicitement -i et -p
dans la commande SSH de chaque backup_script.

11.5 Container Manager

Dans Container Manager, créer un conteneur avec l’image
linuxserver/rsnapshot et monter les volumes suivants :

  • /volume1/NetBackup/conf//config
    (contient rsnapshot.conf)
  • /volume1/NetBackup//volume1/NetBackup/
    (même chemin pour que les chemins absolus de rsnapshot.conf fonctionnent)
  • /volume1/NetBackup/.ssh//root/.ssh/ ou
    /home/backup_user/.ssh/ selon l’utilisateur du conteneur

Important : le chemin /volume1/NetBackup/.ssh/
doit être monté avec les mêmes permissions que celles attendues par SSH
(700 pour le répertoire, 600 pour la clé privée). Si le conteneur tourne en root,
monter vers /root/.ssh/ et adapter le chemin de la clé dans
rsnapshot.conf en conséquence.

11.6 Tester la configuration dans le conteneur

Avant de planifier les tâches, il est essentiel de valider que tout fonctionne
correctement depuis l’intérieur du conteneur. Voici les étapes de test,
de la plus simple à la plus complète.

11.6.1 Vérifier la syntaxe du fichier de configuration

Résultat attendu : Syntax OK. Si une erreur apparaît, c’est
souvent un problème de tabulations (rsnapshot exige des tabulations,
pas des espaces) ou un chemin manquant. L’erreur indiquera la ligne fautive.

11.6.2 Vérifier la connectivité SSH vers chaque serveur

Chaque commande doit afficher OK suivi du hostname du serveur.
Si ça échoue :

  • Permission denied (publickey) → la clé publique n’est pas dans
    authorized_keys côté serveur, ou les permissions de la clé
    privée ne sont pas en 600
  • Connection refused → le port SSH est incorrect ou le
    serveur est arrêté
  • Host key verification failed → première connexion,
    l’option -o StrictHostKeyChecking=accept-new devrait résoudre
    ce problème en acceptant automatiquement la clé hôte la première fois

Première connexion : lors de la toute première connexion SSH
depuis le conteneur, le serveur distant n’est pas encore dans
known_hosts. L’option StrictHostKeyChecking=accept-new
accepte automatiquement la clé hôte si elle n’est pas encore connue, mais
refuse si elle a changé (protection contre les attaques man-in-the-middle).
C’est l’option idéale pour l’automation.

11.6.3 Tester les scripts de pre-backup (dump des bases)

Chaque script doit s’exécuter sans erreur et produire des fichiers
.sql.gz ou .tar.gz datés du jour.

11.6.4 Dry-run rsnapshot (simulation sans transfert)

Cette commande affiche toutes les commandes rsync, ssh et cp que rsnapshot
exécuterait, sans rien faire réellement. Vérifier que :

  • Chaque ligne backup et backup_script est bien listée
  • Les chemins source et destination sont corrects
  • Les options ssh_args contiennent le bon port pour chaque serveur
  • Le cmd_rsync pointe vers /usr/bin/rsync

11.6.5 Premier backup réel (un seul serveur)

Si tous les tests ci-dessus sont concluants, lancer un vrai backup.
Pour limiter le risque, on peut tester avec un seul fichier d’abord :

Le premier hourly sera le plus long (transfert complet).
Les suivants seront rapides grâce aux hard links et au transfert incrémental.
Surveiller les logs en temps réel :

Ordre des tests : toujours valider dans cet ordre :
configtest → SSH → scripts de dump → dry-run → backup réel.
Ne jamais sauter directement au backup réel, car un échec silencieux
(ex: mauvais port SSH) produirait un snapshot vide ou incomplet
sans message d’erreur évident.

Problèmes fréquents rencontrés en pratique : si l’une des
étapes ci-dessus échoue, consulter la section
11.7 Dépannage Synology qui documente les six
problèmes les plus courants rencontrés lors du déploiement depuis un
conteneur Docker Synology : fichier d’exclusion manquant, fins de ligne
Windows dans authorized_keys, IP bannie par fail2ban,
backup_user absent de AllowUsers, blocage par
la double authentification (2FA / Google Authenticator), et permissions
de fichiers incorrectes dans le conteneur.

11.7 Dépannage Synology

Cette section documente les six problèmes concrets rencontrés lors de la
mise en service de rsnapshot depuis un conteneur Docker sur NAS Synology
vers un serveur OVH. Chaque problème est décrit avec son symptôme, son
explication et sa correction.

11.7.1 Fichier d’exclusion rsync manquant

Symptôme : rsnapshot échoue avec une erreur du type
exclude_file /volume1/NetBackup/conf/rsync-exclude does not exist
ou rsync refuse de démarrer.

Cause : la directive exclude_file dans
rsnapshot.conf pointe vers un fichier qui n’a pas encore
été créé.

Correction : créer le fichier avec les exclusions
Linux standard :

Ce fichier est lu par rsync côté client (NAS). Les chemins sont relatifs
à la racine du serveur distant. Les entrées commençant par /
n’excluent que les répertoires à la racine du système de fichiers distant.

11.7.2 Fins de ligne Windows dans authorized_keys

Symptôme : SSH renvoie Permission denied (publickey)
même après avoir vérifié que la bonne clé publique est présente dans
~backup_user/.ssh/authorized_keys. La clé semble correcte
visuellement mais est systématiquement refusée.

Cause : le fichier a été créé ou édité sous Windows
et contient des fins de ligne \r\n (CRLF) au lieu de
\n (LF). SSH refuse silencieusement les clés avec des
caractères \r car ils font partie de la clé analysée.
On peut le détecter avec :

Correction : recréer le fichier avec des fins de ligne
Unix propres. Depuis le serveur cible, en tant que root ou via sudo :

Important : SSH n’affiche aucun message d’erreur
spécifique pour ce problème — la sortie est identique à une clé
simplement absente. C’est l’une des causes les plus difficiles à
diagnostiquer sans penser à vérifier les fins de ligne.

11.7.3 IP bannie par fail2ban

Symptôme : les premières tentatives SSH depuis le
conteneur renvoient Connection refused ou ne reçoivent
pas de réponse du tout, même si le port SSH est correct et que le
serveur est accessible depuis d’autres machines.

Cause : les échecs SSH successifs (dus par exemple
aux problèmes de clé décrits ci-dessus) ont déclenché fail2ban, qui
a banni l’IP du NAS. Sur certains serveurs, il peut exister
deux chaînes iptables fail2ban distinctes : une
chaîne récente f2b-sshd et une ancienne chaîne héritée
fail2ban-SSH. L’IP peut être bannie dans l’une ou l’autre
(ou les deux).

Diagnostic :

Correction immédiate (débannir l’IP) :

Correction permanente (whitelist dans fail2ban) :

L’IP du NAS Synology peut changer si elle est attribuée par DHCP.
Préférer une IP fixe ou une plage CIDR (ex : 82.64.175.0/24)
dans la whitelist pour éviter de devoir la mettre à jour.

11.7.4 backup_user absent de AllowUsers

Symptôme : SSH renvoie Permission denied
immédiatement, sans même demander la clé. Les logs du serveur
(/var/log/auth.log) affichent :
User backup_user from X.X.X.X not allowed because not listed in AllowUsers.

Cause : /etc/ssh/sshd_config contient
une directive AllowUsers qui liste explicitement les
utilisateurs autorisés à se connecter. Si backup_user
n’y figure pas, SSH le refuse systématiquement, quelle que soit la clé.

Correction :

11.7.5 Blocage par la double authentification (2FA / Google Authenticator)

Symptôme : SSH demande un code à usage unique
(Verification code:) alors qu’on s’attend à une connexion
entièrement automatique par clé. Ou bien la connexion échoue avec
Permission denied (publickey,keyboard-interactive) car
rsnapshot ne peut pas répondre interactivement à une invite.

Cause : le serveur impose une authentification
à double facteur (PAM + Google Authenticator) pour tous les
utilisateurs, y compris backup_user. La méthode
d’authentification requise est publickey,keyboard-interactive
ce qui rend l’automatisation impossible.

Correction en deux étapes :

Étape 1 — Exempter backup_user dans PAM
(/etc/pam.d/sshd) : ajouter la ligne d’exemption
avant la ligne pam_google_authenticator.so :

La directive success=done fait que PAM saute toutes les
lignes suivantes du groupe auth pour cet utilisateur,
court-circuitant ainsi Google Authenticator.

Étape 2 — Ajouter un bloc Match dans sshd_config :

Le bloc Match User remplace les directives globales
pour cet utilisateur spécifique : seule la clé publique est acceptée,
et l’authentification par clavier (qui déclenche le code OTP) est
désactivée.

Ordre obligatoire des modifications : modifier PAM
avant de recharger SSH. Sinon, une configuration SSH
incomplète peut verrouiller l’accès à tous les utilisateurs.
Toujours conserver une session SSH ouverte en parallèle lors de
ces modifications.

11.7.6 Permissions incorrectes sur les fichiers dans le conteneur Docker

Symptôme : rsnapshot échoue au démarrage ou SSH
refuse la clé privée avec un message du type
Permissions 0000 for '/volume1/NetBackup/.ssh/id_ed25519_rsnapshot' are too open
ou bad permissions.

Cause : les fichiers montés depuis le volume Synology
dans le conteneur Docker peuvent apparaître avec des permissions
---------- (0000) à l’intérieur du conteneur, indépendamment
de ce que DSM affiche. SSH et rsnapshot refusent de fonctionner
avec des clés dont les permissions sont trop ouvertes ou trop
fermées.

Correction : corriger les permissions depuis
l’intérieur du conteneur :

Ces corrections doivent être refaites si le conteneur est recréé
(par exemple après une mise à jour de l’image). Pour éviter cela,
on peut ajouter un script de démarrage ou utiliser un
entrypoint personnalisé qui applique les permissions
au lancement du conteneur.

11.7.7 Le script de pre-backup échoue avec « Permission denied » sur backup.log

Symptôme : le backup_script (ex: docker-pre-backup.sh)
produit de nombreuses erreurs Permission denied sur
/home/backup_user/backup.log, même si le script lui-même
est exécutable.

Cause : le fichier backup.log a été créé par
root (lors d’un test manuel avec sudo) et appartient
à root:root. Quand backup_user exécute le script
via SSH, il ne peut pas écrire dans un fichier appartenant à root.

Vérifier aussi les droits Docker : si le script
docker-pre-backup.sh exécute des commandes docker exec
pour dumper les bases de données, backup_user doit être
membre du groupe docker :

Principe général : tous les fichiers dans
/home/backup_user/ doivent appartenir à
backup_user:backup_user. Après un test manuel en root,
toujours vérifier avec chown -R backup_user:backup_user /home/backup_user/.

11.7.8 Permission denied sur les dossiers de dumps (bit execute manquant)

Symptôme : le script docker-pre-backup.sh échoue avec
Permission denied sur les dossiers
/home/backup_user/files/mysql/, psql/,
sqlite/, etc. — alors qu’ils appartiennent bien à
backup_user.

Cause : les dossiers ont le mode drw-r----- (640)
au lieu de drwxr-x--- (750). Sans le bit execute
(x) sur un dossier, il est impossible d’y accéder ou d’y créer
des fichiers, même en étant propriétaire. Cela arrive typiquement quand le
script contient chmod -R 640 /home/backup_user/files/ qui applique
640 aussi bien aux fichiers qu’aux dossiers.

Corriger le script pour éviter que le problème ne revienne.
Dans /home/backup_user/bin/docker-pre-backup.sh, remplacer :

Erreur « sudo: a password is required » : si le script
utilise sudo chown / sudo chmod et que ces
commandes ne figurent pas dans le fichier sudoers, elles échoueront
silencieusement lorsque le script est appelé via SSH par rsnapshot.
En pratique, cette erreur est cosmétique : les dumps
sont créés par backup_user (ou via sudo rsync
déjà autorisé) et les fichiers appartiennent déjà au bon utilisateur.
Il n’est pas nécessaire d’ajouter des entrées sudoers supplémentaires.

11.7.9 Restreindre backup_user à l’IP du NAS (sécurité)

Si backup_user est exempté de la double authentification (2FA),
il est fortement recommandé de restreindre sa connexion SSH à l’adresse IP
du NAS uniquement. Ainsi, même en cas de vol de la clé privée, celle-ci
sera inutilisable depuis une autre machine.

Méthode : directive from= dans authorized_keys

Sur chaque serveur distant, éditer le fichier
/home/backup_user/.ssh/authorized_keys et ajouter
la restriction from="IP_DU_NAS" devant la clé publique :

Tester depuis le conteneur rsnapshot :

IP dynamique : si l’IP publique du NAS change régulièrement
(box sans IP fixe), le backup sera bloqué. Dans ce cas, penser à mettre
à jour l’authorized_keys à chaque changement d’IP, ou utiliser
un réseau VPN (WireGuard, Tailscale) pour obtenir une IP stable.

11.8 Planificateur de tâches Synology

11.8.1 Script wrapper (recommandé)

Plutôt que d’appeler docker exec directement, utiliser un script
wrapper qui gère les conflits avec Hyper Backup, le double lancement,
la rotation des logs et la validation des paramètres.

Créer le fichier /volume1/NetBackup/rsnapshot_wrapper.sh :

Fonctionnalités du wrapper :

  • Validation du mode — refuse les fautes de frappe
  • Skip Hyper Backup — ne lance pas rsnapshot si Hyper Backup tourne
  • Lock persistant — dans /volume1/NetBackup/ (survit aux reboots),
    avec détection et nettoyage des locks orphelins (PID mort)
  • Rotation du log — tronque à 10 000 lignes quand le fichier dépasse 50 000 lignes
  • Vérification Docker — distingue « daemon inaccessible » de « conteneur absent »
  • nice -n 19 — priorité CPU basse pour ne pas impacter le NAS

11.8.2 Tâches planifiées

DSM → Panneau de configurationPlanificateur de tâches
créer trois tâches planifiées (Script défini par l’utilisateur) :

Tâche Fréquence Commande
rsnapshot hourly Tous les jours à 01:00 /bin/sh /volume1/NetBackup/rsnapshot_wrapper.sh hourly
rsnapshot daily Dimanche à 01:00 /bin/sh /volume1/NetBackup/rsnapshot_wrapper.sh daily
rsnapshot weekly 1er du mois à 01:00 /bin/sh /volume1/NetBackup/rsnapshot_wrapper.sh weekly
Les noms hourly, daily, weekly
sont des labels de rotation
, pas des fréquences obligatoires.
Lancer rsnapshot hourly une fois par jour est parfaitement valide —
cela crée un nouveau snapshot dans la rotation « hourly ».

11.8.3 Hardlinks et espace disque

rsnapshot utilise des liens durs (hardlinks) : seuls les fichiers
modifiés sont réellement copiés. Les fichiers identiques entre deux
snapshots partagent le même espace disque. Exemple concret :

  • Serveur de 50 Go, 500 Mo modifiés par jour
  • 7 snapshots hourly = ~53 Go réels (pas 350 Go)
  • 7 hourly + 4 daily + 3 weekly ≈ 57 Go

Chaque snapshot apparaît comme un backup complet (navigable normalement),
mais l’espace réel consommé est bien moindre. Vérifier avec :

11.8.4 Coordination avec Hyper Backup

Si le NAS exécute aussi Synology Hyper Backup (sauvegarde vers
un disque USB externe par exemple), il faut éviter que les deux tournent
simultanément pour limiter la contention I/O et garantir la cohérence
des données capturées par Hyper Backup.

Le wrapper gère automatiquement ce cas : si Hyper Backup est détecté
(pgrep synobackup|img_backup|hyperbackup), rsnapshot est
reporté au prochain créneau planifié (SKIP: Hyper Backup détecté
dans le log).

Planification recommandée :

  • rsnapshot : la nuit (ex. 01:00)
  • Hyper Backup : le week-end en journée (ex. samedi 15:00)
Backups longs (> 24 h) : si rsnapshot peut durer plus de 24 heures
(serveurs volumineux), le lock persistant empêche un double lancement le lendemain.
Le backup suivant sera automatiquement reporté jusqu’à la fin du backup en cours.
Hyper Backup, grâce à sa propre planification interne, n’est pas affecté.
En revanche, si rsnapshot tourne encore quand Hyper Backup démarre, Hyper Backup
capturera un état potentiellement en cours de synchronisation — ce qui reste
acceptable car les données ne sont jamais corrompues (cohérence à terme).

Récapitulatif : ce que rsnapshot sauvegarde

Élément Méthode Chemin sauvegardé
Dumps MySQL / MariaDB docker exec + gzip /home/backup_user/files/mysql/*.sql.gz
Dumps PostgreSQL docker exec + gzip /home/backup_user/files/psql/*.sql.gz
Backup SQLite TS3 docker cp DB+WAL + tar /home/backup_user/files/sqlite/*.tar.gz
Dumps MySQL natif (VestaCP) mysqldump + gzip /home/backup_user/files/mysql_native/*.sql.gz
Snapshot Elasticsearch ES snapshot API + tar /home/backup_user/files/elasticsearch/*.tar.gz
docker-compose.yml rsync direct /home/docker/*/docker-compose.yml
Bind mounts Docker rsync direct /home/docker/*/data/, /home/docker/*/config/
Volumes Docker nommés rsync direct /var/lib/docker/volumes/*/_data/
Sites web MyVestaCP rsync direct /home/{{USER_VESTA}}/web/*/
Templates Nginx custom rsync direct /usr/local/vesta/data/templates/web/nginx/
Config système rsync direct /etc/
ownCloud fichiers rsync direct /home/docker/owncloud/data/ (568 Go)
TeamSpeak fichiers rsync direct /home/docker/teamspeak3/data/ (235 Go)

Ce qui n’est PAS sauvegardé (et c’est normal) :
les couches d’images Docker (overlay2/), les conteneurs eux-mêmes,
les caches applicatifs, /proc, /sys, /tmp.
Tout cela se recrée avec un docker compose up -d
et les images se retéléchargent automatiquement.


Sécurité : chiffrement des backups

Les backups contiennent des données sensibles (bases de données,
fichiers utilisateurs, configurations avec mots de passe).
Quelques recommandations :

  • Transfert : déjà chiffré via SSH (rsync over SSH). OK.
  • Stockage : si le disque de backup est un disque externe ou un NAS,
    activer le chiffrement du volume :

    • Serveur dédié : utiliser LUKS pour chiffrer la partition :
      cryptsetup luksFormat /dev/sdX1
    • Synology : activer le dossier partagé chiffré
      dans DSM lors de la création du volume
  • Dumps SQL : les fichiers .sql.gz contiennent les données
    en clair (une fois décompressés). Le chiffrement du volume
    les protège au repos.

Alternative simple : si LUKS est trop complexe à mettre en place,
s’assurer au minimum que le serveur de backup est isolé du réseau public
(pas de port ouvert, accès SSH uniquement par clé) et que le disque
n’est pas accessible physiquement par des tiers.


Article associé : déploiement de serveurs Counter-Strike 1.6 avec Pterodactyl en Docker.


Catégories : Non classé

0 commentaire

Laisser un commentaire

Emplacement de l’avatar

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *