Sauvegarder ses VMs Proxmox avec Proxmox Backup Server (PBS)
La règle est simple et je l’ai apprise à mes dépens avec la VM Gitea…
PBS tourne depuis plusieurs mois sur heighliner et je me félicitais d’avoir mes sauvegardes bien organisées. Puis j’ai relu la définition de la règle 3-2-1 : 3 copies, 2 supports différents, 1 hors site. PBS + le NAS Synology DS414 sur le même réseau local, c’est 2 copies, pas 3, et surtout elles partagent le même site physique. Un incendie, un cambriolage, ou une surtension sérieuse, et je perds tout. Ça méritait une heure de configuration.
Mon upload fibre plafonne à environ 800 Mbps théoriques, mais je ne vais pas saturer le réseau pour des backups homelab. La règle de politesse ici c’est 5 MB/s max en upload – c’est déjà généreux. Les backups PBS sont compressés et dédupliqués, mes 45 GB de données effectives tiennent dans un espace beaucoup plus petit sur le datastore.
Backblaze B2 est la cible évidente pour ce cas d’usage. Les prix 2026 : stockage à $0,006/GB/mois, téléchargement à $0,01/GB. Pour 50 GB de backups, ça donne environ $0,30/mois, soit un peu moins de 4 dollars par an. Ce n’est pas gratuit, mais c’est moins cher qu’une clé USB oubliée dans un tiroir. Et contrairement à la clé USB, ça marche de manière automatique et vérifiable.
Rclone 1.67.x est l’outil de choix pour ce genre de synchronisation. Il supporte B2 nativement, il peut chiffrer les données avant l’upload via son module Crypt, et il s’intègre bien avec un systemd timer. Je ne voulais pas que Backblaze puisse lire mes backups, donc le chiffrement côté client était non négociable.
Sur Debian 12, le paquet apt de Rclone est souvent en retard. Je préfère le script officiel :
curl https://rclone.org/install.sh | sudo bash
rclone --version
D’abord, créer une Application Key Backblaze limitée à un seul bucket, pas la Master Key. Dans la console Backblaze B2 : App Keys > Add a New Application Key, avec accès limité au bucket homelab-backups. La Master Key donne accès à tout le compte – si elle fuit, c’est catastrophique.
rclone config
# New remote > Name: b2-homelab
# Type: 2 (Backblaze B2)
# account: ton-account-id
# key: ta-application-key (pas la master key)
# Laisser le reste par défaut
Tester que ça fonctionne :
rclone lsd b2-homelab:
# devrait lister ton bucket
C’est la couche qui fait que Backblaze ne voit que du bruit blanc. On crée un remote b2-crypt qui s’appuie sur b2-homelab :
rclone config
# New remote > Name: b2-crypt
# Type: crypt
# Remote: b2-homelab:homelab-backups
# Filename encryption: standard
# Directory name encryption: true
# Password: [entrer un mot de passe fort]
# Password2 (salt): [entrer un second mot de passe]
Ne jamais stocker ces mots de passe dans le script de backup. Rclone les écrit dans ~/.config/rclone/rclone.conf avec une obfuscation légère. Ce fichier doit être chmod 600 et appartenir à root si le script tourne en root.
chmod 600 /root/.config/rclone/rclone.conf
ls -la /root/.config/rclone/rclone.conf
# -rw------- 1 root root 512 sep 14 22:10 /root/.config/rclone/rclone.conf
PBS stocke ses datastores sous /var/lib/proxmox-backup/. Le datastore heighliner-backups que j’ai configuré dans l’article 7 de la série est donc accessible directement depuis le système de fichiers. Pas besoin d’exporter : Rclone peut synchroniser directement le répertoire du datastore vers B2 Crypt.
Ne pas modifier les fichiers du datastore PBS directement pendant une synchronisation. Attendre que PBS n’ait pas de job en cours, ou accepter qu’un snapshot en cours soit partiellement uploadé (ce n’est pas grave, il sera complet au prochain run).
La commande de base :
rclone sync
/var/lib/proxmox-backup/heighliner-backups/
b2-crypt:backup/
--bwlimit 5M
--transfers 2
--checkers 4
--log-level INFO
--log-file /var/log/rclone-b2-backup.log
--transfers 2 limite les uploads parallèles. --checkers 4 garde un peu de parallélisme pour la vérification des checksums côté B2. --bwlimit 5M est la limite de bande passante en upload – 5 MB/s, raisonnable pour une fibre domestique.
Ajouter --dry-run lors des premiers tests pour voir ce qui serait transféré sans rien uploader.
Je préfère systemd timers à cron pour les raisons habituelles : logs dans journald, dépendances déclaratives, gestion du OnFailure. Deux fichiers à créer :
/etc/systemd/system/b2-backup.service :
[Unit]
Description=Backup PBS datastore vers Backblaze B2
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=root
Nice=19
IOSchedulingClass=idle
ExecStart=/usr/bin/rclone sync
/var/lib/proxmox-backup/heighliner-backups/
b2-crypt:backup/
--bwlimit 5M
--transfers 2
--checkers 4
--log-level INFO
--log-file /var/log/rclone-b2-backup.log
StandardOutput=journal
StandardError=journal
/etc/systemd/system/b2-backup.timer :
[Unit]
Description=Timer hebdomadaire pour backup B2
[Timer]
OnCalendar=Sat *-*-* 03:00:00
Persistent=true
RandomizedDelaySec=1800
[Install]
WantedBy=timers.target
Le RandomizedDelaySec=1800 introduit un délai aléatoire jusqu’à 30 minutes. C’est une habitude prise pour éviter que tous les services démarrent au même instant pile. Nice=19 et IOSchedulingClass=idle font tourner le process en priorité la plus basse possible, pour ne pas impacter les VMs.
Activer le tout :
systemctl daemon-reload
systemctl enable --now b2-backup.timer
systemctl list-timers b2-backup.timer
Le premier sync de 45 GB a pris 6 heures. Pas un bug, c’est mathématique : 45 GB / 5 MB/s = 9000 secondes, soit 2h30. Avec les overhead Rclone (checksums, chiffrement, requêtes API B2), on arrive facilement à 6 heures pour le premier run complet. J’ai lancé ça un vendredi soir et j’ai retrouvé les logs le samedi matin.
Les runs suivants sont beaucoup plus rapides parce que Rclone ne re-transfère que les fichiers modifiés ou nouveaux. PBS ajoute de nouveaux chunks à chaque backup, mais les chunks existants restent identiques – la déduplication joue en ma faveur aussi pour le transfert réseau.
Un autre point qui m’a surpris : les fichiers du datastore PBS incluent des fichiers d’index .fidx et .didx qui changent à chaque backup PBS même si les données sous-jacentes sont déjà dédupliquées. Ces fichiers sont petits (quelques kB à quelques MB) et se re-synchronisent rapidement. Pas de problème, juste à savoir.
Un backup qu’on n’a jamais restauré n’est pas un backup, c’est une superstition. La procédure de test mensuelle :
# Créer un répertoire de test
mkdir -p /tmp/restore-test
# Copier un snapshot spécifique depuis B2 vers /tmp
rclone copy
b2-crypt:backup/vm/100/
/tmp/restore-test/
--progress
# Vérifier que les fichiers sont lisibles et non corrompus
ls -lah /tmp/restore-test/
# Inspecter un snapshot PBS manuellement si nécessaire
# Nettoyer
rm -rf /tmp/restore-test/
Rclone affiche une barre de progression avec --progress. Pour un test rapide, copier seulement le dernier snapshot d’une petite VM plutôt que tout le datastore.
Pour une restauration réelle, il faudrait pointer PBS vers le répertoire local restauré ou re-importer le snapshot. PBS peut monter un datastore depuis un chemin local – la procédure exacte est dans la documentation PBS sous « Restore from backup ».
45 GB de backups compressés/dédupliqués dans le datastore PBS. En uploadant ça dans B2 :
Stockage : 45 GB × $0,006/GB/mois = $0,27/mois
Opérations d’écriture : négligeables pour un sync hebdomadaire (B2 Class B operations à $0,004/10 000 appels)
Téléchargement : $0 en temps normal, $0,01/GB si je restaure tout un jour
Sur un an : $0,27 × 12 = $3,24, soit environ €3/an. Moins cher qu’une clé USB Kingston 64 GB sur Amazon, et nettement plus fiable.
Le seul coût caché à anticiper : si tu dois restaurer 45 GB depuis B2, ça coûte $0,45 en download. C’est acceptable. Le but d’un backup, c’est d’avoir à restaurer le moins possible, mais d’être capable de le faire quand ça compte.
Trois semaines après la mise en place, le timer a tourné trois fois. Les logs confirment :
2026-09-06 03:12:44 INFO : There was nothing to transfer
2026-09-13 03:08:17 INFO : Transferred: 1.234 GiB in 4 minutes, 23 seconds
2026-09-20 03:11:02 INFO : Transferred: 843.2 MiB in 2 minutes, 58 seconds
Le premier run post-migration était déjà fait. Les deux runs suivants transfèrent uniquement les nouveaux chunks PBS. La règle 3-2-1 est maintenant respectée : PBS local (copie 1), NAS Synology (copie 2 sur support différent), Backblaze B2 (copie 3, hors site, chiffrée).
Il reste un angle mort : les logs Rclone finissent dans /var/log/rclone-b2-backup.log, mais je ne suis pas alerté en cas d’échec. La prochaine étape est d’ajouter une directive OnFailure=notify-failure@%n.service dans le .service, ou de brancher Alertmanager pour surveiller l’exécution du timer. La stack Hubble a déjà tout ce qu’il faut, c’est une question de quelques lignes de config.
Je veux aussi vérifier que le nombre de fichiers dans B2 correspond à ce que PBS expose localement. Un script de réconciliation rapide, peut-être mensuel, pour s’assurer que rien n’a silencieusement échoué à s’uploader.
Cet article est vivant - corrections, contre-arguments et retours de production sont les bienvenus. Trois canaux, choisis celui qui te convient.