Un mini article où je vous propose des scripts pour sauvegarder vos sites web du type PHP+MySQL. C’est toujours plus simple et plus rapide de restaurer depuis des fichiers sur le système plutôt que de faire appel à des outils plus lourd tel que Time Navigator, TSM ou autre. Dans la suite, vous trouverez les scripts ainsi que la doc d’installation de ces derniers.
Préparation
On va créer deux dossiers, un pour les scripts, l’autre pour les sauvegardes. Pour ma part, ces deux dossiers se trouvent dans /root. Suivant comment vous avez partionné votre système, vous pouvez adapter les chemin.
Création de l’arborescence :
cd /root
mkdir scripts
mkdir -p save/www
mkdir -p save/mysql
Script de sauvegarde des fichiers
Ce premier script ne s’occupe de sauvegarder que les fichiers d’un site web, c’est à dire le document root d’un vhost. Si vous avez suivi mon article de configuration Apache, les fichiers pour un vhost spécifique se trouve dans /var/www/
Le script save_www.sh
Ce script crée une archive tar.gz d’un répertoire dans /var/www, puis il fait une rotation de ces archives tar.gz afin de conserver un historique de N jours.
On crée le fichier :
vim /root/scripts/save_www.sh
Copiez collez le script suivant :
#!/bin/bash
# Parametres dossiers
www_root="/var/www"
save_root="/root/save/www"
script_root="/root/scripts"
# Parametres fichiers
www_filter="$script_root/save_www.filter"
www_list="$script_root/save_www.list"
save_error="/root/script.error"
save_log="/var/log/save_www.log"
# On se place dans www_root
cd $www_root
for www_site in `cat "$www_list"`
do
# Archivage fichiers du site
debug=`tar zcvfh "$save_root/$www_site.tar.gz.tmp" "$www_site" --exclude-from "$www_filter"`
# Check reussite commande TAR
if [[ $? -ge "1" ]]
then
# Commande echouee
echo "`date +%d/%m/%y-%H:%M:%S` : Erreur sauvegarde du site $www_site" >> "$save_log"
rm "$save_root/$www_site.tar.gz.tmp"
echo "$debug" > $save_error
exit
fi
# Rotation des archives
for (( i=8; i>0; i-- ))
do
# L'archive precedente
j=`expr $i - 1`
if [[ $j -ge "1" ]]
then
# Check archive existe
if [[ -e "$save_root/$www_site.tar.gz.$j" ]]
then
# La premiere archive ne s'appelle pas .tar.gz.0
debug=`mv "$save_root/$www_site.tar.gz.$j" "$save_root/$www_site.tar.gz.$i"`
# Check reussite commande MV
if [[ $? -ge "1" ]]
then
# Commande echouee
echo "`date +%d/%m/%y-%H:%M:%S` : Erreur mv $www_site.tar.gz.$j vers $www_site.tar.gz.$i" >> "$save_log"
echo "$debug" > $save_error
exit
fi
fi
else
# Check archive existe
if [[ -e "$save_root/$www_site.tar.gz" ]]
then
debug=`mv "$save_root/$www_site.tar.gz" "$save_root/$www_site.tar.gz.$i"`
# Check reussite commande MV
if [[ $? -ge "1" ]]
then
# Commande echouee
echo "`date +%d/%m/%y-%H:%M:%S` : Erreur mv $www_site.tar.gz vers $www_site.tar.gz.$i" >> "$save_log"
echo "$debug" > $save_error
exit
fi
fi
fi
done
# Nouvelle archive
debug=`mv "$save_root/$www_site.tar.gz.tmp" "$save_root/$www_site.tar.gz"`
# Check reussite commande MV
if [[ $? -ge "1" ]]
then
# Commande echouee
echo "`date +%d/%m/%y-%H:%M:%S` : Erreur mv $www_site.tar.gz.tmp vers $www_site.tar.gz" >> "$save_log"
echo "$debug" > $save_error
exit
fi
# Taille nouvelle archive
size_site=`du -hs $save_root/$www_site.tar.gz | awk '{ print $1 }'`
# Log l'archivage
echo "`date +%d/%m/%y-%H:%M:%S` : Sauvegarde du site $www_site [$size_site]" >> "$save_log"
done
# Permissions sur archives
cd $save_root
chmod 400 *
Pensez à ajouter les droits d’exécution :
chmod 754 /root/scripts/save_www.sh
Le fichier save_www.list
Ce fichier liste les sites à sauvegarder. Je considère que chaque site à son propre répertoire dans /var/www. Il suffit de mettre le nom du répertoire pour qu’il soit sauvegarder. Un nom par ligne séparé par un retour chariot.
On crée le fichier :
vim /root/scripts/save_www.list
Exemple de fichier :
blog
wiki
galerie
Le fichier save_www.filter
Ce fichier liste les extensions de fichiers qui ne seront pas sauvegardées. J’exclue en général les .mp3 et les .avi qui peuvent peser très très lourd. A ajuster en fonction de votre besoin et de votre volumétrie.
On crée le fichier :
vim /root/scripts/save_www.filter
Exemple de fichier :
*.mp3
*.MP3
*.avi
*.AVI
Mise en place du cron
On édite la crontab :
crontab -e
On ajoute cette ligne :
# Sauvegarde WWW
0 0 * * * bash /root/scripts/save_www.sh > /dev/null
Rotation des logs
Le script écrit un événement dans un journal à chaque sauvegarde. On va utiliser logrotate.d pour s’assurer que ces journaux gardent une taille raisonnable.
On crée un fichier de conf pour nos journaux :
vim /etc/logrotate.d/save_www
Avec le contenu suivant :
/var/log/save_www.log {
monthly
missingok
rotate 6
}
On recharge la configuration du démon logrotate :
logrotate -f /etc/logrotate.conf
Script de sauvegarde des bases de données
Le script save_mysql.sh
Ce script ressemble à son copain, il fait un dump par base et fait une rotation des dumps afin de garder N jours d’historique.
On crée le fichier :
vim /root/scripts/save_mysql.sh
Copiez collez le script suivant :
#!/bin/bash
# Parametres dossiers
save_root="/root/save/mysql"
script_root="/root/scripts"
# Parametres fichiers
mysql_list="$script_root/save_mysql.list"
save_error="/root/script.error"
save_log="/var/log/save_mysql.log"
# Compte dump mysql
mysql_user="root"
mysql_pass="<password>"
# Dump base par base
for mysql_site in `cat "$mysql_list"`
do
# Dump de la base
debug=`mysqldump -u $mysql_user --password=$mysql_pass --add-drop-table $mysql_site > "$save_root/$mysql_site.sql.tmp"`
# Check reussite commande MYSQLDUMP
if [[ $? -ge "1" ]]
then
# Commande echouee
echo "`date +%d/%m/%y-%H:%M:%S` : Erreur sauvegarde de la base $mysql_site" >> "$save_log"
rm "$save_root/$mysql_site.sql.tmp"
echo "$debug" > $save_error
exit
fi
# Rotation des archives
for (( i=8; i>0; i-- ))
do
# Le dump precedent
j=`expr $i - 1`
if [[ $j -ge "1" ]]
then
# Check dump existe
if [[ -e "$save_root/$mysql_site.sql.$j" ]]
then
# Le premier dump ne s'appelle pas .sql.0
debug=`mv "$save_root/$mysql_site.sql.$j" "$save_root/$mysql_site.sql.$i"`
# Check reussite commande MV
if [[ $? -ge "1" ]]
then
# Commande echouee
echo "`date +%d/%m/%y-%H:%M:%S` : Erreur mv $mysql_site.sql.$j vers $mysql_site.sql.$i" >> "$save_log"
echo "$debug" > $save_error
exit
fi
fi
else
# Check dump existe
if [[ -e "$save_root/$mysql_site.sql" ]]
then
debug=`mv "$save_root/$mysql_site.sql" "$save_root/$mysql_site.sql.$i"`
# Check reussite commande MV
if [[ $? -ge "1" ]]
then
# Commande echouee
echo "`date +%d/%m/%y-%H:%M:%S` : Erreur mv $mysql_site.sql vers $mysql_site.sql.$i" >> "$save_log"
echo "$debug" > $save_error
exit
fi
fi
fi
done
# Nouveau dump
debug=`mv "$save_root/$mysql_site.sql.tmp" "$save_root/$mysql_site.sql"`
# Check reussite commande MV
if [[ $? -ge "1" ]]
then
# Commande echouee
echo "`date +%d/%m/%y-%H:%M:%S` : Erreur mv $mysql_site.sql.tmp vers $mysql_site.sql" >> "$save_log"
echo "$debug" > $save_error
exit
fi
# Taille nouveau dump
size_mysql=`du -hs "$save_root/$mysql_site.sql" | awk '{ print $1 }'`
# Log le dump
echo "`date +%d/%m/%y-%H:%M:%S` : Sauvegarde de la base $mysql_site [$size_mysql]" >> "$save_log"
done
# Permissions sur dumps
cd $save_root
chmod 400 *
Pensez à changer le mot de passe root de la base au début du script. Il est conseillé néanmoins de créer un utilisateur dédié à cette tache.
Pensez à ajouter les droits d’exécution :
chmod 754 /root/scripts/save_mysql.sh
Le fichier save_mysql.list
Dans ce fichier, on liste les bases à sauvegarder. Un nom de base par ligne, avec un retour chariot pour séparer.
On crée le fichier :
vim /root/scripts/save_mysql.list
Exemple de fichier :
mysql
test
blog
Mise en place du cron
On édite la crontab :
crontab -e
On ajoute cette ligne :
# Sauvegarde MySQL
30 0 * * * bash /root/scripts/save_mysql.sh > /dev/null
Rotation des logs
Le script écrit un événement dans un journal à chaque sauvegarde. On va utiliser logrotate.d pour s’assurer que ces journaux gardent une taille raisonnable.
On crée un fichier de conf pour nos journaux :
vim /etc/logrotate.d/save_mysql
Avec le contenu suivant :
/var/log/save_mysql.log {
monthly
missingok
rotate 6
}
On recharge la configuration du démon logrotate :
logrotate -f /etc/logrotate.conf
Conclusion
Deux scripts bash, deux cron et on a une sauvegarde facile a restaurer de ses sites oueb. Il ne faut pas oublier de sauvegarder ensuite le dossier /root/save sur un support externe. Ces sauvegardes servent principalement à remonter un site web qui a été attaqué ou cassé par une modification. En cas de crash serveur, il est souvent plus simple de restaurer la machine entière.
Pour restaurer un site, lancez les commandes suivantes :
cp -p /root/save/www/<site_web>.tar.gz.<chiffre> /tmp/
cp -p /root/save/mysql/<site_web>.sql.<chiffre> /tmp/
tar zxvf /root/save/www/<site_web>.tar.gz.<chiffre>
cd /var/www
rm -rf <site_web>
mv /tmp/<site_web> .
cd /tmp/
mysql -u root -p <site_web> < <site_web>.sql.<chiffre>
rm /tmp/<site_web>.tar.gz.<chiffre>
rm /tmp/<site_web>.sql.<chiffre>
Références
Image Tuxs Siamois : http://tux.crystalxp.net/fr.id.2091-masterlud-tuxs-siamois.html