Sauvegarder automatiquement ses sites web distants chez soi

Je m'occupe et administre plusieurs sites hébergés ailleurs que chez moi, sur un serveur d'hébergement mutualisé. Autrement dit, je n'ai qu'un accès FTP au répertoire www. Aucune sauvegarde n'est donc faite sur ces machines. de temps en temps, quand j'y pense, je fais un backup "manuel" en me connectant en FTP et en rapatriant les données chez moi, puis je vais sur l'interface phpmyadmin et fait un export de la base. Une solution pas terrible, vous en conviendrez.

Depuis que j'ai mon serveur perso chez moi, je me suis dit qu'il serait intéressant d'automatiser cette sauvegarde. Je n'aurai donc plus à me soucier de le faire "manuellement" une fois par mois.

Voici les scripts que j'ai utilisé, ma procédure, mon automatisation, bref, un petit tuto pour sauvegarder automatiquement ses sites web hébergés loin de chez soi.

backup.png

I. L'environnement

Je m'occupe actuellement de 3 "gros" sites 'propulsés par Joomla' hébergés chez un hébergeur qui me propose un accès FTP sur le répertoire www ainsi qu'une base de données que j'administre via phpmyadmin.

Je vais prendre l'exemple du plus gros site que j'administre et que je veux sauvegarder chez moi automatiquement :
  • Un répertoire www de 1,2 Go (1945 répertoires et 20017 fichiers) accessible uniquement en FTP
  • Une base de donnée de plusieurs dizaines de Mo et d'une centaine de tables
  • La base de données n'est pas accessible à distance (je ne peux pas faire un mysqldump de chez moi sur la base)
  • Les modifications sur le www ne sont pas fréquentes, en revanche, les modifications sur la base sont nombreuses et quotidiennes
  • Les backups du www via FTP durent environ 1h30, 2h (très grand nombre de petits fichiers et grosses photos)
  • Je veux une sauvegarde mensuelle pour le répertoire www et une sauvegarde hebdomadaire pour la base de données.
Voila pour les données de base. Voici comment je fais pour sauvegarder tout ça.

II. La sauvegarde


La sauvegarde va se dérouler en 3 étapes : la sauvegarde de la base de données (qui, elle aussi, va se découper en 2 temps), la sauvegarde du répertoire www et enfin, l'automatisation de tout cela.

  • La base de données
Comme je vous l'ai dit, je ne peux pas accéder directement à la base depuis chez moi. Si j'avais pu, un simple mysqldump aurait fait l'affaire. Si vous avez un accès distant sur votre base, vous pouvez passer cette étape. Ici, c'est un peu plus compliqué : il faut générer un mysqldump sur la machine distante puis récupérer le dump en FTP.

Il faut donc, dans un premier temps, écrire le script de génération de dump. Ce sera un script php que nous appelleront, via curl, dans notre script shell de backup (voir après).
<?php
$host = 'myhost';
$user = 'myuser';
$db = 'mydatabase';
$password = 'mypassword';
 
system("mysqldump --host=$host --user=$user --password=$password $db > $db.sql");
#On vire l'ancienne version gzippée du dump
system("rm $db.sql.gz");
#On gzip la nouvelle version
system("gzip $db.sql");
?>
À ma racine www, j'ai créé un répertoire backup dans lequel j'ai ajouté ce script backup.php. Ainsi, dès qu'on appellera la page http://monsite.fr/backup/backup.php, un dump mydatabase.sql.gz sera généré dans ce répertoire backup.

Ensuite, sur mon serveur je créé mon script shell de backup de mysql :
#!/bin/bash
#Ce script fait un backup de la BDD et la récupère en ftp
#
FICHIER_DUMP='/www/backup/mydatabase.sql.gz'
FICHIER_DEST='/sauvegardes/monsite/mysql/mydatabase.sql.gz'
MAIL_CONTACT='mail@me.fr'
 
#On génère le fichier sur le serveur (voir ci-dessus)
curl -s http://monsite.fr/backup/backup.php
sleep 10

#On vire l'ancienne version sur le serveur
rm -f $FICHIER_DEST
 
#On ramène le fichier sauvegardé via ftp sur notre serveur
lftp ftp://login:pass@ftp.monsite.fr -e "get $FICHIER_DUMP -o $FICHIER_DEST ; quit"
 
RET=$?
if [ $RET -gt 0 ]
then
MESSAGE="Erreur de dump de la base $FICHIER_DUMP"
echo $MESSAGE | /usr/bin/mail -s "Erreur sur le serveur" $MAIL_CONTACT
fi

lftp ftp://login:pass@ftp.monsite.fr -e "rm $FICHIER_DUMP ; quit"

Explications :
  • La variable FICHIER_DUMP contient le chemin sur le serveur distant du dump généré avec le script php backup.php
  • La variable FICHIER_DEST contient le chemin où sera stocké le dump sur mon serveur
  • Le MAIL_CONTACT est l'adresse mail où sera envoyé un mail d'erreur (s'il y en a une)
  • Grâce à curl, j'interroge mon script php qui, nous l'avons vu, génère mon dump sur le serveur distant
  • J'enlève l'ancien backup de mon serveur
  • J'utilise le programme lftp pour rapatrier, en FTP, le dump ainsi généré. La commande est assez claire je pense
  • Je contrôle que la commande s'est bien passée, le cas contraire, j'envoie un mail
  • Enfin, je supprime le dump sur le site distant (par précaution, merci JN)
On a désormais un script qui génère le dump sur le site distant et le ramène sur notre serveur. Nous verrons après pour l'automatisation de ce script.

  • Le répertoire www
Maintenant que ma base de données est sauvegardée, je vais sauvegarder mon répertoire www. Pour ce faire, j'ai fait ce script :

#!/bin/bash
#Ce script fait un backup du www en ftp
#
REP_DUMP='/www/'
REP_DEST='/sauvegardes/monsite/www/'
FICHIER_LOG='/sauvegardes/monsite/backup.log'
MAIL_CONTACT='mail@me.fr'
 
 
echo "*****************************************************************" >> $FICHIER_LOG
/bin/date >> $FICHIER_LOG
echo "Backup en cours" >> $FICHIER_LOG


#Ici, on sauvegarde tout sauf le répertoire compteur
lftp ftp://login:pass@ftp.monsite.fr -e "mirror -e -x cours/ -x logs/ $REP_DUMP $REP_DEST ; quit"
 
RET=$?
RETOUR=`expr $RETOUR + $RET`
if [ $RET -gt 0 ]
then
MESSAGE="Erreur de backup sur $REP_DEST\\n"
echo $MESSAGE | /usr/bin/mail -s "Erreur sur le serveur" $MAIL_CONTACT
fi


/bin/date >> $FICHIER_LOG
/usr/bin/du -hs $REP_DEST >> $FICHIER_LOG
echo "Backup terminé" >> $FICHIER_LOG
echo "*****************************************************************" >> $FICHIER_LOG

echo "Voir fichier $FICHIER_LOG" | /usr/bin/mail -s "Backup monsite OK" $MAIL_CONTACT

Explications :
  • La variable REP_DUMP contient le nom du répertoire distant à sauvegarder
  • La variable REP_DEST et FICHIER_LOG contiennent respectivement le chemin où sera sauvegardé le site sur mon serveur et le fichier de log qu'il génèrera
  • Le MAIL_CONTACT est l'adresse mail où sera envoyé un mail d'erreur (s'il y en a une)
  • Je commence par écrire l'heure de départ du script dans le fichier de log puis "Backup en cours"
  • J'utilise, là aussi, lftp pour rapatrier le site. La commande mirror permet d'avoir une copie parfaite du site distant (les répertoires supprimées du www seront effacés aussi sur mon serveur, etc.). Le paramètre -x me permet d'exclure certain répertoires de la sauvegarde. Voir cette page pour plus de détails sur la commande lftp.
  • Je contrôle que la commande s'est bien passée, le cas contraire, j'envoie un mail
  • J'écris la date et l'heure de fin du script dans le fichier de log.
On a désormais un script qui récupère et synchronise notre site distant sur notre serveur.
Notez qu'on pourrait, si on voulait être bien synchro, lancer l'exécution du script de sauvegarde de la base de données dans ce script. Ainsi, on ferait un backup de la base et on rapatrierait l'ensemble en même temps.

III. L'automatisation

Une fois que ces scripts sont prêts (ont peut les tester "à la main" pour s'en assurer), il ne nous reste plus qu'à tout automatiser grâce au cron. Pour ceux qui ne connaissent pas le cron, j'en ai fait un cours dans cet article.

Pour faire rapide, voici ma crontab :
#Backup des BDD des sites distants (hebdomadaire, le dimanche soir)
45 23 * * 0 /home/moi/scripts/backup_mysql_sitedistant.sh >/dev/null 2>&1

#Backup du www des sites distants (une fois par mois, la premiere nuit)
0 1 1 * * /home/moi/scripts/backup_www_sitedistant.sh >/dev/null 2>&1

Explications :
  • J'exécute mon script de sauvegarde de la base de données tous les dimanches à 23h45
  • J'exécute mon script de sauvegarde du répertoire www tous les 1er du mois à 1h du matin

IV. Conclusion

Voici donc comment je sauvegarde mes sites distants, en attendant de tous les remettre directement sur mon serveur, ce qui simplifiera bien les choses.
Je pense que ces scripts sont perfectibles, si vous avez des idées, n'hésitez pas à me les suggérer, je suis toujours à l'affut des bons conseils :)


Edit : Pour ceux qui essayent, les chemins d'accès on tous été changés dans mes scripts d'exemple et c'est pas mon blog que je sauvegarde automatiquement, donc n'essayez plus d'aller sur generation-linux.fr/backup ;)
Vus : 2029
Publié par Génération Linux : 126