Sauvegardes, surveillance et la routine mensuelle

Savoir ce qui mérite d'être sauvegardé sur le serveur, et ce qui ne le mérite pas. Une copie chiffrée hors site faite chaque nuit par restic, avec une restauration réellement testée ; un email quand le site tombe ou que la sauvegarde n'a pas tourné ; des logs qui ne peuvent plus remplir le disque ; et dix minutes de vérification une fois par mois.

intermédiaire~40 min de manipulation
#backup#restic#s3#monitoring#systemd#ovh#debian

Pas encore validée de bout en bout — sois le premier.Signaler un problème

Brouillon — pas encore exécuté de bout en bout. Cette page est écrite mais son auteur ne l'a pas encore déroulée sur une vraie machine. Des commandes peuvent être fausses : lis avant de lancer, et dis-nous ce qui casse.

En un coup d'œilSauvegardé de trois façons, surveillé de l'extérieur
Ton VPS
readsencrypted, nightlywhole disk, dailyHTTPS every 5 minemail if down
Config, certificats, racine web/etc · /var/lib/caddy · /home ·
resticnightly · 7d / 4w / 6m
Bucket S3
Sauvegarde OVHdaily · 1 day kept
Ton sitehttps://
Sonde de disponibilitéevery 5 min · keyword
Toi

Chaque nuit, restic lit la configuration et les certificats du serveur, les chiffre et les envoie dans un bucket hors du VPS ; OVH garde sa propre copie du disque entier. Une sonde externe interroge le site toutes les cinq minutes et t'écrit quand il ne répond plus.

Le site est en ligne. Cette page fait en sorte que, le jour où quelque chose casse, tu sois le premier au courant et que tu puisses tout remettre en place. Tu décides de ce qui mérite d'être sauvegardé, tu trouves les sauvegardes d'OVH, tu envoies chaque nuit une copie chiffrée hors site avec restic, tu restaures une fois pour prouver que ça marche, tu mets une surveillance externe sur le site, tu plafonnes les logs, et tu termines par une routine de dix minutes à faire une fois par mois.

Avant de commencer

Les pages 3 à 6 sont faites : tu te connectes avec ssh vps, Caddy sert le site en HTTPS, et les déploiements passent par vps-deploy. Tout ce qui suit se lance sur le serveur après ssh vps, en , sauf les tableaux de bord web et les blocs marqués pour le Mac.

Vérification
$systemctl is-active caddy
Retour attendu
active

Quoi sauvegarder

La source du site ne vit que dans le dossier du projet sur ton Mac, : c'est de là que le site se reconstruit et se redéploie en quelques minutes (pages 1 et 6). Ce que le Mac ne sait pas reconstruire, c'est l'état du serveur lui-même.

CheminCe qu'il contientSi tu le perds
/etcLe fichier SSH complémentaire, le Caddyfile, les règles ufw, les jails fail2ban, les sources apt, sudoers, utilisateurs et groupesRefaire les pages 3 à 5 à la main : une heure ou deux, avec de la place pour les erreurs
/var/lib/caddyLes certificats TLS et le compte ACMECaddy en obtient de nouveaux tout seul, dans les limites de Let's Encrypt
/homeTes fichiers de config perso, les authorized_keys des deux utilisateurs, tes scriptsRemettre les clés par la console KVM
Les releases construites, pas la source : ni code, ni originauxRedéploie depuis le Mac ; cette copie ne sert que si le Mac et sa sauvegarde ont disparu tous les deux
/var/lib/<app> (plus tard)Les données d'un backend, quand tu en ajouteras unIrremplaçable : la vraie raison d'être des sauvegardes

Sauvegardes et snapshots OVH

Dans l'espace client OVH, ouvre ton VPS (Bare Metal Cloud → Serveurs privés virtuels → le VPS). L'onglet Accueil liste les options : Sauvegarde automatique et Snapshot.

  • Sauvegarde automatique : incluse avec le VPS, une par jour, un jour de rétention. Le ... à côté → Restaurer.
  • Snapshot : une option payante. Tu le prends à la main, avant un changement risqué : une montée de version majeure de Debian, une config Caddy dont tu n'es pas sûr, un changement de pare-feu.

Créer le bucket et les clés

La copie hors site part vers un stockage objet S3 : un bucket, plus un utilisateur S3 dont restic utilise les clés. Chez OVH, dans l'espace client :

  1. Public Cloud → crée un projet si tu n'en as pas (il faut un moyen de paiement).
  2. Object Storage → Créer un conteneur d'objets : API S3, classe standard, région GRA (Gravelines), nom .
  3. Object Storage → Utilisateurs S3 → crée un utilisateur, donne-lui lecture/écriture sur le conteneur, et copie sa clé d'accès et sa clé secrète dans le panneau des valeurs et dans ton gestionnaire de mots de passe.

Mettre en place restic

restic fait des snapshots chiffrés et dédupliqués de répertoires dans un « dépôt », ici le bucket. Installe-le, puis écris ses identifiants dans un fichier que seul root peut lire.

Serveur·
$sudo apt install -y restic
$sudo install -d -m 700 /etc/restic
$sudo install -m 600 /dev/null /etc/restic/env

Puis écris les identifiants dedans : copie la commande et colle-la dans le terminal. Le fichier existe déjà en mode 600, et tee garde ce mode : seul root peut lire les secrets.

Serveur·écrit un fichier/etc/restic/env
RESTIC_REPOSITORY=s3:/
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
RESTIC_PASSWORD=

Ensuite la liste de ce qu'on ignore, /etc/restic/excludes :

Serveur·écrit un fichier/etc/restic/excludes
/home/*/.cache
/var/lib/caddy/.local/share/caddy/locks

Et le dépôt lui-même :

Serveur·
$sudo bash -c 'set -a; . /etc/restic/env; restic init'
Si restic init échoue
  • The specified bucket does not exist : le nom du bucket ou la région du point d'accès ne correspond pas. Compare avec l'espace client.
  • Access Denied ou SignatureDoesNotMatch : mauvaises clés, ou l'utilisateur S3 n'a pas de droits sur le conteneur.
  • Une erreur de région : ajoute AWS_DEFAULT_REGION=gra (ta région, en minuscules) dans /etc/restic/env.
  • config file already exists : le dépôt est déjà initialisé, rien à faire.

Pour modifier /etc/restic/env à la main :

Serveur·
$sudo vim /etc/restic/env

Maintenant le travail de nuit : un service systemd qui fait la sauvegarde et élague les vieux snapshots, et un timer qui le lance.

Avec healthchecks.io, la dernière ligne le pingue après une sauvegarde réussie. Son URL vient du check que tu crées plus bas, dans « Être prévenu quand ça casse » : le bloc se copie une fois rempli, alors crée d'abord le check, ou reviens à ce bloc ensuite.

Serveur·écrit un fichier/etc/systemd/system/restic-backup.service
[Unit]
Description=Nightly restic backup to off-site S3
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env
Environment=RESTIC_CACHE_DIR=/var/cache/restic
CacheDirectory=restic
Nice=10
ExecStart=/usr/bin/restic backup /etc /var/lib/caddy /home --exclude-file=/etc/restic/excludes --tag nightly
ExecStartPost=/usr/bin/restic forget --prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6
ExecStartPost=-/usr/bin/curl -fsS -m 10 --retry 3 -o /dev/null

Copie chaque bloc et colle-le dans le terminal du serveur : chacun écrit son fichier. Puis active le timer et lance une sauvegarde tout de suite :

Serveur·
$sudo systemctl daemon-reload
$sudo systemctl enable --now restic-backup.timer
$sudo systemctl start restic-backup.service
Vérification
$systemctl is-active restic-backup.timer
Retour attendu
active
Vérification
$sudo systemctl show -p Result restic-backup.service
Retour attendu
Result=success

Tester une restauration

Une sauvegarde jamais restaurée est un espoir, pas une sauvegarde. Restaure la configuration de Caddy dans un dossier de test et compare-la avec celle en service :

Serveur·
$sudo bash -c 'set -a; . /etc/restic/env; restic restore latest --target /tmp/restore-test --include /etc/caddy'
$sudo diff -r /etc/caddy /tmp/restore-test/etc/caddy && echo "restore OK"
Vérification
$sudo diff -r /etc/caddy /tmp/restore-test/etc/caddy && echo 'restore OK'
Retour attendu
restore OK

Ensuite, supprime la copie de test avec sudo rm -rf /tmp/restore-test.

Être prévenu quand ça casse

Un service externe interroge le site depuis internet et t'envoie un email quand il ne répond plus. UptimeRobot en est un exemple ; Better Stack et d'autres marchent pareil. Crée un compte gratuit et ajoute une sonde :

  • Type Keyword (mot-clé), URL https:///, toutes les 5 minutes.
  • Mot-clé : un mot que seule ta vraie page d'accueil contient, par exemple ton nom dans le titre.
  • Contact d'alerte : .

La sonde surveille le site ; healthchecks.io surveille la sauvegarde. Il marche dans l'autre sens : ton serveur le pingue après chaque sauvegarde, et il t'écrit quand le ping n'arrive pas. Sur healthchecks.io, crée un compte puis Add Check :

  • Période 1 day, délai de grâce 2 hours.
  • Intégrations : email vers (actif par défaut pour l'adresse du compte).
  • Copie l'URL de ping, affichée sur la page du check, dans . Si tu as déjà écrit restic-backup.service plus haut, recopie son bloc (il contient maintenant l'URL) et colle-le sur le serveur, puis recharge systemd et lance une sauvegarde :
Serveur·
$sudo systemctl daemon-reload
$sudo systemctl start restic-backup.service

Garder les logs sous contrôle

Par défaut, journald garde jusqu'à 10 % du disque, plafonné à 4 Go. Sur un VPS de 40 Go, plafonne-le à 500 Mo avec un fichier complémentaire, /etc/systemd/journald.conf.d/size.conf :

Serveur·
$sudo mkdir -p /etc/systemd/journald.conf.d
Serveur·écrit un fichier/etc/systemd/journald.conf.d/size.conf
[Journal]
SystemMaxUse=500M

Copie la commande et colle-la dans le terminal, puis redémarre journald et regarde sa taille :

Serveur·
$sudo systemctl restart systemd-journald
$journalctl --disk-usage
Vérification
$systemd-analyze cat-config systemd/journald.conf | grep '^SystemMaxUse'
Retour attendu
SystemMaxUse=500M

La routine mensuelle

Dix minutes, une fois par mois, le même jour chaque mois. Depuis ton portable, ssh vps, puis :

Serveur·
Commande sensible — redémarre ou éteint la machine. Vérifie avant d'exécuter.
$# 1. Paquets à mettre à jour : installe-les avec sudo apt upgrade
$sudo apt update && apt list --upgradable
$# 2. Après une mise à jour du noyau : sudo reboot, puis vérifie le site
$[ -f /var/run/reboot-required ] && echo "reboot needed"
$# 3. L'occupation du disque doit rester sous 80 %
$df -h /
$# 4. Adresses bannies (si fail2ban a été choisi page 3) : rien à faire, sauf si l'une est la tienne
$sudo fail2ban-client status sshd 2>/dev/null || echo "fail2ban not installed"
$# 5. Attendu : "0 loaded units listed"
$systemctl --failed
$# 6. Les erreurs du mois : lis-les une fois, cherche les nouvelles
$sudo journalctl -p err --since '30 days ago' | tail -n 30

Ensuite les sauvegardes : le timer montre le prochain passage, et le dernier snapshot doit dater de la nuit dernière.

Serveur·
$systemctl list-timers restic-backup.timer
$sudo bash -c 'set -a; . /etc/restic/env; restic snapshots --latest 3'

Pour finir, ouvre le tableau de bord de la sonde et regarde la disponibilité et les incidents du mois. Puis, sur le Mac, vérifie que Time Machine a sauvegardé le dossier du projet récemment :

Mac
$tmutil latestbackup

Terminé

L'état de ton serveur est sauvegardé de trois façons, et une restauration a fait ses preuves. Tu reçois un email quand le site ne répond plus, les logs ne peuvent plus remplir le disque, et une routine mensuelle vérifie que tout ça tient.

La page suivante, Checklist de lancement, repasse sur tout une dernière fois avant que tu annonces le site.

Tout a fonctionné ?

Si tu as suivi cette page jusqu'au bout sur une vraie machine, dis-le. Ta validation est datée et enregistre ta stack : le prochain lecteur sur le même chemin sait que ça marche toujours.

Cette copie est en lecture seule. Pour dire que ça marche, ou que ça ne marche pas, ouvre une issue

Seuls tes choix de stack sont enregistrés, jamais tes valeurs. Le pseudo reste sur ce navigateur.