Auto-héberger un site sur un VPS coûte quelques euros par mois et rend la main sur toute la pile. En contrepartie, la sauvegarde devient une responsabilité pleine : aucun hébergeur mutualisé ne veille en arrière-plan. Un serveur sans sauvegarde testée n’est pas « à risque », il est en panne différée. Ce guide décrit une méthode complète et reproductible pour un site WordPress ou PHP : base de données, fichiers, externalisation chiffrée, rotation et — surtout — restauration vérifiée.
Pourquoi la sauvegarde « quand on y pense » échoue toujours
Une sauvegarde manuelle repose sur une décision humaine répétée, exactement le type de tâche qu’un emploi du temps chargé fait sauter en premier. Elle échoue de trois façons prévisibles : elle n’est pas lancée assez souvent, elle vit sur le même disque que le site — donc disparaît avec lui — et elle n’est jamais restaurée pour vérifier qu’elle fonctionne. Une sauvegarde jamais testée n’est qu’une hypothèse. L’objectif d’une bonne méthode est de retirer l’humain de la boucle quotidienne et de ne le rappeler que pour un test de restauration mensuel.
La règle 3-2-1, version petit serveur
La règle 3-2-1 reste le repère le plus solide : trois copies des données, sur deux supports différents, dont une hors site. Sur un VPS modeste, elle se décline sans matériel coûteux.
| Copie | Emplacement | Rôle |
|---|---|---|
| Données de production | Disque du VPS | La source, en service |
| Sauvegarde locale | Second volume ou dossier dédié | Restauration rapide |
| Sauvegarde externe | Stockage objet chiffré (S3, B2) | Survie à la perte du VPS |
Deux points comptent plus que le reste : la copie externe doit être chiffrée avant de quitter le serveur, et la copie locale ne dispense jamais de la copie externe. Un incident qui détruit le VPS emporte les deux volumes s’ils sont sur la même machine.
Sauvegarder la base de données proprement
Pour un site dynamique, la base contient l’essentiel : contenus, comptes, commandes. Un dump cohérent se fait sans verrouiller les tables, avec une transaction unique sur un moteur transactionnel comme InnoDB.
#!/usr/bin/env bash
# Sauvegarde de la base : dump compresse, date dans le nom
set -euo pipefail
STAMP=$(date +%F_%H%M)
DEST=/var/backups/db
mkdir -p "$DEST"
mariadb-dump --single-transaction --quick --lock-tables=false \
--defaults-extra-file=/root/.my.cnf ma_base \
| gzip -9 > "$DEST/ma_base_$STAMP.sql.gz"
Le fichier d’identifiants ~/.my.cnf évite d’écrire le mot de passe dans la commande, donc dans l’historique du shell et dans la table des processus. Il doit être lisible par le seul compte qui sauvegarde, en droits 600.
Sauvegarder les fichiers du site
Côté fichiers, tout ne se vaut pas : le code et les médias téléversés doivent être sauvegardés, les caches et les journaux n’ont aucun intérêt et gonflent inutilement l’archive. Un rsync incrémentiel vers un volume local est rapide et lisible.
# Fichiers du site : incrementiel via rsync vers un disque local
rsync -aH --delete \
--exclude 'wp-content/cache' \
--exclude '*.log' \
/var/www/monsite/ /var/backups/files/monsite/
L’option --delete maintient le miroir local strictement aligné sur la source ; à manier en connaissance de cause, car une suppression côté site se propage à la copie locale. C’est précisément pour cela que la copie locale ne suffit pas : la rétention se joue au niveau externe.
Externaliser et chiffrer avec restic
La copie hors site est celle qui sauve d’un incendie de salle machine ou d’un compte compromis. restic chiffre côté client, déduplique et parle nativement au stockage objet — l’archive part illisible pour l’hébergeur du dépôt.
# Externaliser + chiffrer avec restic (depot sur stockage objet S3)
export RESTIC_REPOSITORY="s3:https://s3.example.com/backups-monsite"
export RESTIC_PASSWORD_FILE=/root/.restic-pass
export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=...
restic backup /var/backups/db /var/backups/files --tag nightly
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
La commande forget --prune applique la politique de rétention et libère réellement l’espace des instantanés écartés. Le mot de passe du dépôt vit dans un fichier hors du dépôt : le perdre rend les sauvegardes définitivement illisibles.
Où stocker la copie externe
Le choix du dépôt hors site pèse sur le coût et sur la vitesse de restauration. Trois familles se distinguent pour un site auto-hébergé. Le stockage objet compatible S3 — Backblaze B2, Scaleway, OVH, Wasabi — facture au gigaoctet stocké et reste le plus souple ; les frais de sortie varient fortement d’un fournisseur à l’autre et méritent d’être lus avant de s’engager. Un service dédié à la sauvegarde comme rsync.net expose un accès SSH et s’accorde bien avec restic ou un simple rsync. Enfin, un second serveur déjà maîtrisé peut jouer le rôle de dépôt, à condition d’être physiquement distinct du premier. La règle discriminante reste la même : le fournisseur ne doit jamais pouvoir lire le contenu, ce que le chiffrement côté client de restic garantit quel que soit le dépôt.
Automatiser avec cron et fixer la rétention
Réunis dans un script unique, ces gestes se planifient en une ligne. Une nuit creuse limite l’impact du dump sur la base en production.
# /etc/cron.d/backup-monsite -> 3h15 chaque nuit, journalise la sortie
15 3 * * * root /usr/local/sbin/backup-monsite.sh >> /var/log/backup.log 2>&1
La rétention équilibre coût de stockage et profondeur d’historique. Le tableau ci-dessous correspond à un site de contenu classique.
| Fréquence conservée | Durée |
|---|---|
| Quotidienne | 7 jours |
| Hebdomadaire | 4 semaines |
| Mensuelle | 6 mois |
Cette politique garde une trentaine d’instantanés, assez pour rattraper une corruption découverte tardivement sans exploser la facture de stockage objet.
Tester la restauration : l’étape que tout le monde saute
C’est le seul contrôle qui prouve que la chaîne fonctionne. Une fois par mois, une restauration dans un dossier jetable suffit à valider l’intégrité de l’archive et à entretenir le geste, pour qu’il ne soit pas découvert un jour de panne réelle.
# Tester la restauration dans un dossier jetable, une fois par mois
restic snapshots
restic restore latest --target /tmp/restore-test
gunzip < /tmp/restore-test/var/backups/db/ma_base_*.sql.gz | head -n 40
Une sauvegarde jamais restaurée n’est pas une sauvegarde, c’est une hypothèse.
Repère. Deux indicateurs cadrent tout plan de reprise : le RPO, quantité de données que l’on accepte de perdre (ici, jusqu’à 24 h avec un rythme quotidien), et le RTO, temps de remise en service visé. Les diviser par deux coûte plus cher — sauvegardes plus fréquentes, restauration répétée — et cet arbitrage se décide avant l’incident, pas pendant.
Ce qu’il faut retenir
Une sauvegarde fiable tient en quatre exigences : automatisée pour ne dépendre de personne, séparée du serveur pour survivre à sa perte, chiffrée avant de sortir, et restaurée régulièrement pour prouver qu’elle vaut quelque chose. La règle 3-2-1, un script en cron et un test mensuel couvrent l’essentiel des cas d’un site auto-hébergé.
La seule vraie frayeur de sauvegarde que j’ai vécue ne venait pas d’un disque mort mais d’un dump corrompu que personne n’avait jamais rouvert : le fichier existait, il était vide. Depuis, je considère qu’une sauvegarde non testée n’existe pas, et je mets le rappel de restauration mensuelle avant l’automatisation elle-même dans mes installations clientes. Pour un site de contenu, restic vers un stockage objet à quelques euros par mois est le meilleur rapport tranquillité/prix que je connaisse. — Simon Janvier
Pour aller plus loin
Documentation officielle de restic, dépôt et politiques de rétention : restic.readthedocs.io.
