Credit : Illustration backtotheweb.fr
Automatiser ses backups avec un script Bash et cron
Automatiser ses backups avec un script Bash et cron
Ne pas avoir de sauvegardes, c'est jouer avec le feu. Voici comment mettre en place un systeme de backup automatise et fiable sur votre serveur IONOS avec un simple script Bash et cron.
Structure du script
Creez le fichier /usr/local/bin/backup.sh :
#!/bin/bash
set -euo pipefail
# === CONFIGURATION ===
BACKUP_DIR="/home/backups"
DATE=$(date +%Y-%m-%d_%H%M)
RETENTION_DAYS=14
LOG_FILE="/var/log/backup.log"
# Sites a sauvegarder
WEB_DIR="/var/www"
# Base de donnees
DB_USER="backup_user"
DB_PASS="MotDePasseBackup!"
DATABASES=("wordpress_db" "prestashop" "app_production")
# Serveur distant (optionnel)
REMOTE_HOST="backup@stockage.exemple.fr"
REMOTE_DIR="/backups/serveur-ionos"
# === FONCTIONS ===
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
check_space() {
local available=$(df -BG "$BACKUP_DIR" | tail -1 | awk '{print $4}' | tr -d 'G')
if [ "$available" -lt 5 ]; then
log "ERREUR : Espace disque insuffisant (${available}G restants)"
exit 1
fi
}
# === DEBUT DU BACKUP ===
log "========== Debut du backup $DATE =========="
# Creer le repertoire du jour
BACKUP_PATH="$BACKUP_DIR/$DATE"
mkdir -p "$BACKUP_PATH/databases"
mkdir -p "$BACKUP_PATH/files"
# Verifier l'espace disque
check_space
# === SAUVEGARDE DES BASES DE DONNEES ===
log "Sauvegarde des bases de donnees..."
for DB in "${DATABASES[@]}"; do
log " -> Dump de $DB"
mysqldump \
--user="$DB_USER" \
--password="$DB_PASS" \
--single-transaction \
--routines \
--triggers \
--quick \
--lock-tables=false \
"$DB" | gzip > "$BACKUP_PATH/databases/${DB}.sql.gz"
if [ ${PIPESTATUS[0]} -eq 0 ]; then
log " -> $DB : OK ($(du -sh "$BACKUP_PATH/databases/${DB}.sql.gz" | cut -f1))"
else
log " -> $DB : ERREUR"
fi
done
# === SAUVEGARDE DES FICHIERS ===
log "Sauvegarde des fichiers web..."
tar -czf "$BACKUP_PATH/files/web.tar.gz" \
--exclude='*/node_modules' \
--exclude='*/vendor' \
--exclude='*/.git' \
--exclude='*/cache' \
--exclude='*/wp-content/cache' \
"$WEB_DIR" 2>/dev/null
log " -> Fichiers web : $(du -sh "$BACKUP_PATH/files/web.tar.gz" | cut -f1)"
# Sauvegarder les configurations systeme
log "Sauvegarde des configurations..."
tar -czf "$BACKUP_PATH/files/configs.tar.gz" \
/etc/nginx/sites-available \
/etc/php \
/etc/fail2ban/jail.local \
/etc/ssh/sshd_config \
/etc/crontab \
2>/dev/null
log " -> Configs : $(du -sh "$BACKUP_PATH/files/configs.tar.gz" | cut -f1)"
# === SYNCHRONISATION DISTANTE ===
if [ -n "$REMOTE_HOST" ]; then
log "Synchronisation vers le serveur distant..."
rsync -avz --delete \
"$BACKUP_PATH" \
"$REMOTE_HOST:$REMOTE_DIR/" \
>> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
log " -> Sync distante : OK"
else
log " -> Sync distante : ERREUR"
fi
fi
# === ROTATION DES ANCIENS BACKUPS ===
log "Nettoyage des backups de plus de $RETENTION_DAYS jours..."
find "$BACKUP_DIR" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;
log " -> Nettoyage termine"
# === RESUME ===
TOTAL_SIZE=$(du -sh "$BACKUP_PATH" | cut -f1)
log "Taille totale du backup : $TOTAL_SIZE"
log "========== Backup termine avec succes =========="
Preparer l'environnement
chmod +x /usr/local/bin/backup.sh
mkdir -p /home/backups
Creez un utilisateur MySQL dedie aux sauvegardes :
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'MotDePasseBackup!';
GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES, EVENT ON *.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;
Planifier avec cron
Editez le crontab de root :
crontab -e
Ajoutez la ligne :
# Backup quotidien a 3h du matin
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
Tester le script
Lancez-le manuellement et verifiez les resultats :
/usr/local/bin/backup.sh
ls -la /home/backups/
cat /var/log/backup.log
Verifier l'integrite
Testez regulierement la restauration de vos sauvegardes :
# Tester un dump SQL
gunzip -t /home/backups/2026-03-15_0300/databases/wordpress_db.sql.gz
# Tester une archive tar
tar -tzf /home/backups/2026-03-15_0300/files/web.tar.gz > /dev/null
Une sauvegarde qui n'a jamais ete testee n'est pas une sauvegarde. Automatisez, mais verifiez.