Script shell de sauvegarde des fichiers associés à un blog WordPress

Dans la lignée du script de sauvegarde quotidienne des bases de données, je me suis dis qu’il serait bon également de sauvegarder les fichiers associés au fonctionnement du site, parmi lesquels on peut citer (pour un blog WordPress) les images uploadées, les différents plugins installés, les fichiers du thèmes, etc. Le problème vient quand on a plusieurs sites sur le même serveur, et donc il est à mon avis compliqué de gérer au cas par cas ce qu’il faut sauvegarder ou non. Notez également que, en terme de place, les fichiers texte (tous les fichiers de code source en premier lieu) se compressent très bien, donc il n’est pas un problème de les sauvegarder tous.

Or, comme chacun sait, au fur et à mesure de l’utilisation de tel ou tel CMS (ex : WordPress, Dotclear, Joomla, etc), CRM (VtigerCRM) ou autre logiciel installé sur un serveur, on finit par rajouter des personnalisations ici et , et bien sûr on ne se souvient jamais de l’intégralité de ce que l’on a fait.

Pour ma part, j’ai donc choisi de sauvegarder l’intégralité du dossier /var/www, même si c’est assez lourd en terme d’espace disque. A cela, j’ai ajouté les fichiers de configuration de chaque serveur fonctionnant sur le serveur (pour moi, Apache et Nginx).

Le script shell suivant fait en fait d’abord une copie des dossiers/fichiers à sauvegarder dans un répertoire temporaire (qu’il aura créé juste avant), puis les mets dans une archive gzipée. J’attire votre attention sur le fait que chez moi, avec un dossier /var/www de 740Mo (c’est pas tant que ça), le script a fait tourner le CPU à 100% pendant environ 8 minutes. Pendant ce temps là, les pages ont très bien été servies (j’ai fait le test), et d’après ce que je voyais sur htop, il y avait une gestion des processus permettant à Apache et Nginx de fonctionner correctement, laissant au script le reste du CPU disponible. Toutefois, les quelques observations que je note ici sont à prendre avec des pincettes, elles ne sont le fruit d’aucune étude sérieuse, c’est pourquoi je recommande de n’exécuter le script qu’au milieu de la nuit (entre 3h00 et 6h00), pour avoir un impact éventuel sur les performances aussi limité que possible. De même, il faut bien voir que la quantité de fichiers associés peut être assez importante, et la taille de l’archive également, donc si vous n’avez pas beaucoup d’espace disque sur votre serveur, évitez de multiplier les backups (pour ma part, je pense qu’une à deux fois par semaine me suffiront amplement).

Voilà le script shell :

#!/bin/bash

#User Variables
DATE=/bin/date;
NOW=`$DATE '+%Y-%m'-%d_04_30`;
NBBACKUP=4;
BACKUPDIR=/home/the_user/filesbackup;
BACKUPTEMPDIR=/home/the_user/filesbackup/tmp;

APACHECONFDIR=/etc/apache2;
NGINXCONFDIR=/etc/nginx;
WWWDIR=/var/www;

#Command Variables
RM=/bin/rm;
CP=/bin/cp;
MKDIR=/bin/mkdir;
MV=/bin/mv;
TAR=/bin/tar;
SCP=/bin/scp

$MKDIR $BACKUPTEMPDIR;
$CP -R $APACHECONFDIR $BACKUPTEMPDIR;
$CP -R $NGINXCONFDIR $BACKUPTEMPDIR;
$CP -R $WWWDIR $BACKUPTEMPDIR;
$TAR -czf $BACKUPDIR/files_backup.$NOW.0.tgz $BACKUPTEMPDIR/;
$RM -R $BACKUPTEMPDIR/

#$SCP -P 50000 $BACKUPDIR/*0.tgz user@ndd.com:/chemin

i=$(($NBBACKUP-1))
j=$NBBACKUP
$RM -f $BACKUPDIR/*$NBBACKUP.tgz
while [ $i -ge 0 ];
do
     for f in $BACKUPDIR/*.$i.tgz;
     do
         $MV $f ${f/.$i.tgz/.$j.tgz};
     done
     j=$(($j-1))
     i=$(($i-1))
done

Veuillez noter que celui-ci n’est pas optimisé pour le listing des opérations à réaliser. J’ai tenté le for i in chemin_1 chemin_2, mais l’interpréteur shell n’a pas voulu dans la mesure où il considérait les chemin comme des dossiers, et ne voulait apparemment pas boucler dessus.

Vers la fin, vous pourrez voir une ligne commentée, celle pour la commande scp, qui nécessite que vous ayez un serveur supplémentaire sous la main (ou un hébergement web) qui accepte les connexions scp.

Pour ce qui est de la sauvegarde d’un nombre défini de backups, je remercie Tym, c’est lui qui a donné la solution.

7 réflexions sur « Script shell de sauvegarde des fichiers associés à un blog WordPress »

  1. Je ne comprend pas ton problème de bouclage sur les chemins…
    Pour ma part un :
    « #!/bin/bash

    FOO=/tmp/foo
    BAR=/tmp/bar

    for i in $FOO $BAR;do
    cp -R $i /tmp/backup/
    done
     »

    fonctionne très bien…

    Tu peux détailler un peu, ton souci m’intéresse 🙂

  2. @Tym: Voilà le script ft.sh (de test) que j’ai fait :

    #!/bin/bash

    #User Variables
    APACHECONFDIR=/filesbackup/test1
    NGINXCONFDIR=/filesbackup/test2
    WWWDIR=/filesbackup/test3

    LISTDIR=`$APACHECONFDIR $NGINXCONFDIR $WWWDIR`;

    TARGETDIR=/filesbackup/testfinale;

    #Command Variables
    CP=/bin/cp;

    for i in $LISTDIR;do
    $CP -R i $TARGETDIR;
    done;

    et ça me donne :

    user@myserv/filesbackup $ ./ft.sh
    ./ft.sh: line 8: /filesbackup/test1: is a directory

    Donc je pense que c’est la concaténation des différents paths qui ne colle pas…

  3. @Louis:

    Cela vient de ta définition de « TARGETDIR ». les « «  » servent à évaluer l’expression en question : par exemple :

    DATE=`date`

    mettra le résultat de la commande « date » dans « $DATE ».

    Si tu définit « TARGETDIR » comme ceci :

    LISTDIR="$APACHECONFDIR $NGINXCONFDIR $WWWDIR";

    ça va fonctionner. Attention, utilise bien des double quotes (« ) et non des simples (‘), sinon le shell ne va pas interpréter le contenu des variables.

  4. Petits souci d’interprétation des quotes et anti-quotes dans le commentaire…j’imagine que tu as l’idée 🙂

  5. (refonte complète de mes commentaires précédents, tu peux les supprimer)
    @Louis:

    Cela vient de ta définition de LISTDIR.

    Voici l’utilisation des quotes en bash :
    " " : bash interprète le contenu (echo "$VAR" affiche le contenu de $VAR)
    ' ' : bash n’interprète pas le contenu (echo '$VAR affiche $VAR en tant que texte)
    ` ` : bash exécute le contenu (comme ce que tu fait dans ton script complet : NOW=`$DATE '+%Y-%m'-%d_04_30`;)

    Dans ton cas, tu essaye en fait d’exécuter la commande /filesbackup/test1 /filesbackup/test2 /filesbackup/test3, inutile de dire que bash ne peux pas « exécuter » des répertoires. Voila le pourquoi de l’erreur que tu obtient.

    Si tu définit LISTDIR comme ceci :

    LISTDIR= »$APACHECONFDIR $NGINXCONFDIR $WWWDIR »;

    ça va fonctionner. Utilise bien des " " !

  6. Bonjour

    Je trouve le script bien mais si je veux virer la sauvegarde sur un autre serveur via ftp, faudrait faire comment ?

Les commentaires sont fermés.