Time Machine est la solution de sauvegarde intégrée à macOS. Simple à utiliser, elle présente des limites : format propriétaire, chiffrement optionnel, impossible de sauvegarder vers un NAS Linux ou du stockage cloud S3, et politique de rétention peu flexible. Restic est une alternative open source : rapide, sûr, dédupliquant, chiffré de bout en bout, et compatible de nombreuses destinations (disque local, NAS, SFTP, S3, ).
Dans cet article nous mettons en place une sauvegarde automatique sur macOS avec Restic : installation, dépôt chiffré sur disque externe, script de sauvegarde, automatisation via LaunchAgent et notification Discord.
Pourquoi Restic plutôt que Time Machine ?
| Fonctionnalité | Time Machine | Restic |
|---|---|---|
| Chiffrement | Optionnel (APFS chiffré) | Systématique (AES-256) |
| Déduplication | Liens durs uniquement | Déduplication par blocs |
| Destinations | Disque local, Time Capsule | Local, SFTP, S3, Azure, GCS… |
| Restauration partielle | Via l’interface graphique | CLI, granularité au fichier près |
| Rétention configurable | Automatisée, peu flexible | Totalement paramétrable |
| Vérification intégrité | Limitée | restic check avec hachage complet |
| Format | Propriétaire | Open source, portable |
Prérequis
- macOS 12 Monterey ou supérieur (testé sur macOS 26.5 Tahoe, Apple Silicon M2 Pro)
- Homebrew installé (brew.sh)
- Un disque externe USB-C ou un NAS/stockage cloud comme destination
Installation de Restic
# Installation via Homebrew brew install restic # Verifier la version installee restic version
Initialisation du dépôt
Un dépôt Restic (repository) est le répertoire où toutes les sauvegardes sont stockées de façon dédupliquante et chiffrée. Il doit être initialisé une seule fois. Dans notre exemple, le disque externe est monté sous /Volumes/ExternalDrive.
# Creer le fichier de mot de passe (ne jamais commiter dans git) echo "VotreMotDePasseTresLong" > ~/.restic_password chmod 600 ~/.restic_password # Initialiser le depot sur le disque externe restic init --repo /Volumes/ExternalDrive/restic-backup --password-file ~/.restic_password
Ce mot de passe est le seul moyen de déchiffrer les données. Conservez-le précieusement dans un gestionnaire de mots de passe.
Première sauvegarde manuelle
# Sauvegarder Documents et scripts restic backup ~/Documents ~/scripts \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password \ --verbose # Lister les snapshots existants restic snapshots \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password
Script de sauvegarde
Créer le fichier /opt/homebrew/bin/restic_backup.sh et le rendre exécutable :
touch /opt/homebrew/bin/restic_backup.sh chmod 755 /opt/homebrew/bin/restic_backup.sh nano /opt/homebrew/bin/restic_backup.sh
Contenu du script (adapter DISCORD_WEBHOOK, REPO et SOURCES à votre configuration) :
#!/bin/bash
# Sauvegarde Restic automatique - macOS
RESTIC_BIN="/opt/homebrew/bin/restic"
REPO="/Volumes/ExternalDrive/restic-backup"
PASSWORD_FILE="$HOME/.restic_password"
LOG_FILE="/opt/homebrew/var/log/restic_backup.log"
DISCORD_WEBHOOK="https://discord.com/api/webhooks/VOTRE_WEBHOOK_ICI"
# Sources a sauvegarder
SOURCES=("$HOME/Documents" "$HOME/scripts")
# Verifier que le disque est monte
if [ ! -d "$REPO" ]; then
echo "[$(date)] ERREUR : depot introuvable" >> "$LOG_FILE"
curl -s -X POST "$DISCORD_WEBHOOK" -H "Content-Type: application/json"
-d '{'""content"': "":x: **Restic** : depot introuvable""}' -o /dev/null
exit 1
fi
echo "[$(date)] Debut de la sauvegarde..." >> "$LOG_FILE"
START=$(date +%s)
# Lancer la sauvegarde
"$RESTIC_BIN" backup "${SOURCES[@]}" \
--repo "$REPO" \
--password-file "$PASSWORD_FILE" \
--verbose \
>> "$LOG_FILE" 2>&1
BACKUP_EXIT=$?
# Appliquer la politique de retention (1 mois glissant)
if [ $BACKUP_EXIT -eq 0 ]; then
"$RESTIC_BIN" forget \
--repo "$REPO" \
--password-file "$PASSWORD_FILE" \
--keep-within 1m \
--prune \
>> "$LOG_FILE" 2>&1
fi
END=$(date +%s)
DURATION=$((END - START))
MINUTES=$((DURATION / 60))
SECONDES=$((DURATION % 60))
# Notification Discord
if [ $BACKUP_EXIT -eq 0 ]; then
MSG="✅ **Restic** : sauvegarde OK en ${MINUTES}m${SECONDES}s"
else
MSG="❌ **Restic** : ERREUR (code $BACKUP_EXIT)"
fi
JSON="{\"content\": \"$MSG\"}"
curl -s -X POST "$DISCORD_WEBHOOK" -H "Content-Type: application/json" -d "$JSON" -o /dev/null
echo "[$(date)] Fin - code $BACKUP_EXIT (${MINUTES}m${SECONDES}s)" >> "$LOG_FILE"
exit $BACKUP_EXIT
⚠️ Le webhook Discord se récupère dans les paramètres du salon Discord : Intégrations → Webhooks → Créer un webhook.
Automatisation avec un LaunchAgent
Sur macOS, les tâches planifiées se configurent via des LaunchAgents — l’équivalent des crontabs Linux, avec une meilleure intégration système.
# Creer le repertoire LaunchAgents si necessaire mkdir -p ~/Library/LaunchAgents
Créer le fichier ~/Library/LaunchAgents/local.restic_backup.plist :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.restic_backup</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/restic_backup.sh</string>
</array>
<!-- Lancement tous les jours a 02h00 -->
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>2</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
<key>StandardOutPath</key>
<string>/opt/homebrew/var/log/restic_backup.log</string>
<key>StandardErrorPath</key>
<string>/opt/homebrew/var/log/restic_backup.log</string>
<key>RunAtLoad</key>
<false/>
</dict>
</plist>
# Charger le LaunchAgent launchctl load ~/Library/LaunchAgents/local.restic_backup.plist # Verifier qu'il est bien charge launchctl list | grep restic # Tester manuellement launchctl start local.restic_backup # Modifier l'heure : editer le plist puis recharger launchctl unload ~/Library/LaunchAgents/local.restic_backup.plist launchctl load ~/Library/LaunchAgents/local.restic_backup.plist
Restaurer des fichiers
Lister les snapshots
restic snapshots \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password
ID Time Host Paths a1b2c3d4 2026-06-01 02:00:05 macmini /Users/user/Documents, /Users/user/scripts e5f6g7h8 2026-06-02 02:00:03 macmini /Users/user/Documents, /Users/user/scripts
Restaurer un snapshot complet
restic restore latest \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password \ --target /tmp/restic-restore
Restaurer un fichier ou dossier spécifique
# Restaurer un sous-dossier precis restic restore latest \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password \ --include "/Users/user/Documents/Projets" \ --target /tmp/restic-restore # Restaurer depuis un snapshot specifique (ID du snapshot) restic restore a1b2c3d4 \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password \ --include "/Users/user/Documents/important.pdf" \ --target /tmp/restic-restore
Vérifier l’intégrité du dépôt
# Verification rapide (structure du depot) restic check \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password # Verification complete avec lecture des donnees restic check --read-data \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password
Politique de rétention
# Garder 1 mois glissant (notre configuration) restic forget --keep-within 1m --prune \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password # Politique granulaire : 7 quotidiens + 4 hebdos + 3 mensuels restic forget \ --keep-daily 7 --keep-weekly 4 --keep-monthly 3 \ --prune \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password # Dry-run : voir ce qui serait supprime sans agir restic forget --keep-within 1m --dry-run \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password
Commandes utiles
# Statistiques du depot (taille totale, gain deduplication) restic stats \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password # Chercher un fichier dans tous les snapshots restic find "*.pdf" \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password # Comparer deux snapshots restic diff a1b2c3d4 e5f6g7h8 \ --repo /Volumes/ExternalDrive/restic-backup \ --password-file ~/.restic_password # Voir les logs de la derniere sauvegarde tail -50 /opt/homebrew/var/log/restic_backup.log
Simplifier les commandes avec des variables d’environnement
Pour éviter de répéter --repo et --password-file à chaque commande, ajouter dans ~/.zshrc :
# Dans ~/.zshrc export RESTIC_REPOSITORY="/Volumes/ExternalDrive/restic-backup" export RESTIC_PASSWORD_FILE="$HOME/.restic_password" # Recharger source ~/.zshrc # Les commandes deviennent simplement : restic snapshots restic backup ~/Documents ~/scripts restic check
Aller plus loin : sauvegarder vers un NAS ou le cloud
Restic supporte nativement de nombreuses destinations distantes :
# Sauvegarde vers un NAS via SFTP restic init --repo "sftp:user@nas.local:/backup/restic" --password-file ~/.restic_password restic backup ~/Documents --repo "sftp:user@nas.local:/backup/restic" --password-file ~/.restic_password # Sauvegarde vers un bucket S3 export AWS_ACCESS_KEY_ID="votre_key" export AWS_SECRET_ACCESS_KEY="votre_secret" restic init --repo "s3:s3.amazonaws.com/nom-bucket" --password-file ~/.restic_password
La règle 3-2-1 recommande 3 copies des données, sur 2 supports différents, dont 1 hors site. Restic s’y prête parfaitement : disque externe local ou vers un NAS distant.
Conclusion
Restic offre une solution de sauvegarde robuste, flexible et chiffrée pour macOS. Comparé à Time Machine, il donne un contrôle total sur les données, la destination et la politique de rétention, tout en restant simple en ligne de commande. Couplé à un LaunchAgent et des notifications Discord, c’est un système de sauvegarde professionnel entièrement automatisé.
La déduplication par blocs optimise l’espace : si 90 % des fichiers n’ont pas changé depuis la dernière sauvegarde, seuls 10 % sont stockés — permettant de conserver plusieurs mois d’historique sur un disque modeste.
