Dans notre série d’articles baptisés LSCI (La sauvegarde c’est important), nous vous avons déjà présenté pas mal de méthodes de sauvegarde. Ici, nous voulons vous présenter la méthode que nous utilisons pour sauvegarder ce site web. Dans ce tutoriel, nous allons donc voir comment sauvegarder son serveur web grâce à un script.

Nous passerons en revue toutes les parties de ce script pour vous donner des excplications au fur et à mesure de l’avancement du tuto.

Création du script

Dans cette première partie, nous débuter la création de notre script par la définition de nos variables. Ces variables serviront à ne pas avoir à définir certaines informations plus tard. Nous allons y définir toutes sortes de choses comme les chemins d’accès aux exécutables, le format de la date, les logins et mots de passe utilisés, le fichier de logs utilisé ainsi que les couleurs qui seront utilisées dans les fichiers de logs.

#!/bin/bash
# Made by REWOP it (https://techarea.fr)
# With this, you can make a backup of your websites (full)

# Variables
tar_bin="/bin/tar"
date_day=`/bin/date +%Y%m%d`
dir_backup_web="/backup/${date_day}/sites"
dir_sites="/var/www"
mysqldump_bin="/usr/bin/mysqldump"
mysql_bin="/usr/bin/mysql"
dir_backup_db="/backup/${date_day}/databases"
gzip_bin="/bin/gzip"
rclone_bin="/usr/sbin/rclone"
date_old=`date --date='10 days ago' +%Y%m%d`
dir_backup="/backup/"
mysql_user="user"
mysql_password="PWD"
logfile="/var/log/backup/backup_${date_day}.log"
ret="0"

# Define the color for function showmsg()
green="\\033[0;32m"
stand="\\033[0;39m"
red="\\033[0;31m"
yellow="\\033[33m"

Nous allons maintenant créer la fonction qui permettra aux messages affichés sur l’écran et dans les logs de ressortir en couleur. Nous utiliserons une couleur différente pour chaque type de message.

# Function for show the message on screen and log file
# Use this function with this example (return success message without log / return error message with log)
# do_showmsg "success" "nolog" "Backup is valid"
# do_showmsg "error" "log" "Config file is not found"
do_showmsg() {

        # Local variables
        local usecolor="$1"
        local uselog="$2"
        local usemsg="$3"

        # Function logs
        if [ "${uselog}" == "log" ] || [ "${uselog}" == "yes" ]; then
                returnlog=${logfile}
        else
                returnlog="/dev/null"
        fi

        # Function colors
        if [ "${usecolor}" == "info" ] || [ "${usecolor}" == "warn" ]; then
                echo -ne "${stand}[  ${yellow}INFO  ${stand}]> ${usemsg}\n" >> ${returnlog}
        elif [ "${usecolor}" == "error" ] || [ "${usecolor}" == "ko" ]; then
                echo -ne "${stand}[  ${red}ERROR  ${stand}]> ${usemsg}\n" >> ${returnlog}
        elif [ "${usecolor}" == "success" ] || [ "${usecolor}" == "ok" ]; then
                echo -ne "${stand}[ ${green}SUCCESS ${stand}]> ${usemsg}\n" >> ${returnlog}
        else
                echo -ne "${stand}[  ${stand}OUTPUT  ${stand}]> ${usemsg}\n" >> ${returnlog}
        fi
}

Vérifions ensuite si tous les paquets nécessaires sont installés sur notre système. S’il ne le sont pas, le script les installera automatiquement.

# Check if needed packages are installed
if [ $(dpkg-query -W -f='${Status}' lftp 2>/dev/null | grep -c "ok installed") -eq 0 ]
then
  apt-get install lftp
fi
if [ $(dpkg-query -W -f='${Status}' tar 2>/dev/null | grep -c "ok installed") -eq 0 ]
then
  apt-get install tar
fi
if [ $(dpkg-query -W -f='${Status}' gzip 2>/dev/null | grep -c "ok installed") -eq 0 ]
then
  apt-get install gzip
fi

Créons maintenant le dossier qui contiendra les logs d’exécution. Ici, le script va regarder si le dossier existe déjà. Si il n’est pas encore présent, il le créera.

# Log folder creation
if [ ! -e "/var/log/backup" ]
    then mkdir -p "/var/log/backup"
        else do_showmsg "info" "log" "Folder '/var/log/backup' already exist"
fi

Passons maintenant à la partie sauvegarde des dossiers contenant vos sites. Dans cette partie, nous allons d’abord créer le dossier qui contiendra les sauvegardes fichiers de nos sites webs. Ensuite, nous créons une boucle pour permettre de faire une archive par dossier se trouvant dans /var/www.

# Starting script
echo -ne "Starting backup all websites at `/bin/date +%d/%m/%Y`, `/bin/date +%H:%M:%S`\n" >> ${logfile}

# Création du dossier s'il n'existe pas
if [ ! -e "${dir_backup_web}" ]
    then mkdir -p "${dir_backup_web}"
    else do_showmsg "info" "log" "Folder '${dir_backup}' already exist"
fi

# Sauvegarde des sites dans "/datas/sites/*"
cd ${dir_sites}
for site_list in `ls`; do
    tar czf ${dir_backup_web}/backup_${site_list}.tar.gz ${site_list} 2>&1 > /dev/null
    if [ -e "${dir_backup_web}/backup_${site_list}.tar.gz" ]
        then echo -ne "[ SUCCESS ]> ${dir_backup_web}/backup_${site_list}.tar.gz\n" >> ${logfile}
        else echo -ne "[  ERROR  ]> ${dir_backup_web}/backup_${site_list}.tar.gz\n" >> ${logfile}
    fi
done

# Stopping script
echo -ne "Starting backup all websites at `/bin/date +%d/%m/%Y`, `/bin/date +%H:%M:%S`\n" >> ${logfile}

C’est maintenant aux bases de données d’être sauvegardées. Nous partons sur le même principe que pour les dossiers de nos sites.

# Starting script
echo -ne "Starting backup MySQL Databases at `/bin/date +%d/%m/%Y`, `/bin/date +%H:%M:%S`\n" >> ${logfile}

# Création du répertoire de sauvegarde
if [ ! -e "${dir_backup_db}" ]
    then mkdir -p "${dir_backup_db}"
    else echo -ne "[  INFO  ]> folder '${dir_backup}' already exist\n" >> ${logfile}
fi

# Sauvegarde des bases de données avec compression GZIP
for database_list in `${mysql_bin} -u ${mysql_user} -p${mysql_password} -ss -e "SHOW DATABASES" | egrep -vi "^(information_schema|performance_schema)$"`; do
    ${mysqldump_bin} -u ${mysql_user} -p${mysql_password} --events --opt -Q -B ${database_list} | ${gzip_bin} -c > ${dir_backup_db}/backup_${database_list}.sql.gz
    if [ -e "${dir_backup_db}/backup_${idatabase}.sql.gz" ]
        then echo -ne "[ SUCCESS ]> ${dir_backup_db}/backup_${database_list}.sql.gz\n" >> ${logfile}
        else echo -ne "[  ERROR  ]> ${dir_backup_db}/backup_${database_list}.sql.gz\n" >> ${logfile}
    fi
done

# Stopping script
echo -ne "Stopping backup MySQL Databases at `/bin/date +%d/%m/%Y`, `/bin/date +%H:%M:%S`\n" >> ${logfile}

La partie sauvegarde étant maintenant terminée, nous allons envoyer nos sauvegardes du jour vers un espace de stockage externe comme un FTP ou un stockage Cloud type Google Drive ou Amazon Drive. La première chose faire avant d’envoyer la sauvegarde est de vérifier elle sauvegarde existe. Ici, nous avons décidé les stocker sur Amazon Drive. A la fin de la copie, nous supprimons le backup du jour.

# Vérification du dossier de sauvegarde d'aujourd'hui (sinon arrêt du script)
if [ ! -e "${dir_backup}/${date_day}" ]; then
    echo -ne "[  ERROR  ]> Le dossier de sauvegarde local '${dir_backup}/${date_day}' n'existe pas.\n" >> ${logfile}
    exit 1
fi

# Upload the backups files on Amazon Drive and return code
cd ${dir_backup}
${rclone_bin} copy ${date_day} amzn:Backup/websites/${date_day}

if [ "$?" -eq "0" ]; then
        do_showmsg "success" "log" "Uploading backup on Amazon Drive successfull"
        ret=$((${ret}+0))
else
        do_showmsg "error" "log" "Uploading backup on Amazon Drive return an error"
        ret=$((${ret}+1))
fi

rm -rf /backup

Voilà, le script étant expliqué, nous allons maintenant vous le livrer au complet pour une copie plus facile. Si vous décidez d’utiliser ce script il vous faudra installer Rclone pour connecter votre compte de stockage cloud ou alors modifier les lignes concernant l’envois des backups.

Présentation du script complet

#!/bin/bash
# Made by REWOP it (https://techarea.fr)
# With this, you can make a backup of your websites (full)
 
# Variables
tar_bin="/bin/tar"
date_day=`/bin/date +%Y%m%d`
dir_backup_web="/backup/${date_day}/sites"
dir_sites="/var/www"
mysqldump_bin="/usr/bin/mysqldump"
mysql_bin="/usr/bin/mysql"
dir_backup_db="/backup/${date_day}/databases"
gzip_bin="/bin/gzip"
rclone_bin="/usr/sbin/rclone"
date_old=`date --date='10 days ago' +%Y%m%d`
dir_backup="/backup/"
mysql_user="user"
mysql_password="PWD"
logfile="/var/log/backup/backup_${date_day}.log"
ret="0"

# Define the color for function showmsg()
green="\\033[0;32m"
stand="\\033[0;39m"
red="\\033[0;31m"
yellow="\\033[33m"

# Function for show the message on screen and log file
# Use this function with this example (return success message without log / return error message with log)
# do_showmsg "success" "nolog" "Backup is valid"
# do_showmsg "error" "log" "Config file is not found"
do_showmsg() {

        # Local variables
        local usecolor="$1"
        local uselog="$2"
        local usemsg="$3"

        # Function logs
        if [ "${uselog}" == "log" ] || [ "${uselog}" == "yes" ]; then
                returnlog=${logfile}
        else
                returnlog="/dev/null"
        fi

        # Function colors
        if [ "${usecolor}" == "info" ] || [ "${usecolor}" == "warn" ]; then
                echo -ne "${stand}[  ${yellow}INFO  ${stand}]> ${usemsg}\n" >> ${returnlog}
        elif [ "${usecolor}" == "error" ] || [ "${usecolor}" == "ko" ]; then
                echo -ne "${stand}[  ${red}ERROR  ${stand}]> ${usemsg}\n" >> ${returnlog}
        elif [ "${usecolor}" == "success" ] || [ "${usecolor}" == "ok" ]; then
                echo -ne "${stand}[ ${green}SUCCESS ${stand}]> ${usemsg}\n" >> ${returnlog}
        else
                echo -ne "${stand}[  ${stand}OUTPUT  ${stand}]> ${usemsg}\n" >> ${returnlog}
        fi
}

# Check if needed packages are installed
if [ $(dpkg-query -W -f='${Status}' lftp 2>/dev/null | grep -c "ok installed") -eq 0 ]
then
  apt-get install lftp
fi
if [ $(dpkg-query -W -f='${Status}' tar 2>/dev/null | grep -c "ok installed") -eq 0 ]
then
  apt-get install tar
fi
if [ $(dpkg-query -W -f='${Status}' gzip 2>/dev/null | grep -c "ok installed") -eq 0 ]
then
  apt-get install gzip
fi

# Log folder creation
if [ ! -e "/var/log/backup" ]
    then mkdir -p "/var/log/backup"
        else do_showmsg "info" "log" "Folder '/var/log/backup' already exist"
fi

# Starting script
echo -ne "Starting backup all websites at `/bin/date +%d/%m/%Y`, `/bin/date +%H:%M:%S`\n" >> ${logfile}

# Création du dossier s'il n'existe pas
if [ ! -e "${dir_backup_web}" ]
    then mkdir -p "${dir_backup_web}"
    else do_showmsg "info" "log" "Folder '${dir_backup}' already exist"
fi

# Sauvegarde des sites dans "/datas/sites/*"
cd ${dir_sites}
for site_list in `ls`; do
    tar czf ${dir_backup_web}/backup_${site_list}.tar.gz ${site_list} 2>&1 > /dev/null
    if [ -e "${dir_backup_web}/backup_${site_list}.tar.gz" ]
        then echo -ne "[ SUCCESS ]> ${dir_backup_web}/backup_${site_list}.tar.gz\n" >> ${logfile}
        else echo -ne "[  ERROR  ]> ${dir_backup_web}/backup_${site_list}.tar.gz\n" >> ${logfile}
    fi
done

# Stopping script
echo -ne "Starting backup all websites at `/bin/date +%d/%m/%Y`, `/bin/date +%H:%M:%S`\n" >> ${logfile}

# Starting script
echo -ne "Starting backup MySQL Databases at `/bin/date +%d/%m/%Y`, `/bin/date +%H:%M:%S`\n" >> ${logfile}

# Création du répertoire de sauvegarde
if [ ! -e "${dir_backup_db}" ]
    then mkdir -p "${dir_backup_db}"
    else echo -ne "[  INFO  ]> folder '${dir_backup}' already exist\n" >> ${logfile}
fi

# Sauvegarde des bases de données avec compression GZIP
for database_list in `${mysql_bin} -u ${mysql_user} -p${mysql_password} -ss -e "SHOW DATABASES" | egrep -vi "^(information_schema|performance_schema)$"`; do
    ${mysqldump_bin} -u ${mysql_user} -p${mysql_password} --events --opt -Q -B ${database_list} | ${gzip_bin} -c > ${dir_backup_db}/backup_${database_list}.sql.gz
    if [ -e "${dir_backup_db}/backup_${idatabase}.sql.gz" ]
        then echo -ne "[ SUCCESS ]> ${dir_backup_db}/backup_${database_list}.sql.gz\n" >> ${logfile}
        else echo -ne "[  ERROR  ]> ${dir_backup_db}/backup_${database_list}.sql.gz\n" >> ${logfile}
    fi
done

# Stopping script
echo -ne "Stopping backup MySQL Databases at `/bin/date +%d/%m/%Y`, `/bin/date +%H:%M:%S`\n" >> ${logfile}


#######################
##  PART FTP BACKUP  ##
#######################

# Vérification du dossier de sauvegarde d'aujourd'hui (sinon arrêt du script)
if [ ! -e "${dir_backup}/${date_day}" ]; then
    echo -ne "[  ERROR  ]> Le dossier de sauvegarde local '${dir_backup}/${date_day}' n'existe pas.\n" >> ${logfile}
    exit 1
fi

# Upload the backups files on the Amazon Drive and return code
cd ${dir_backup}
${rclone_bin} copy ${date_day} amzn:Backup/websites/${date_day}

if [ "$?" -eq "0" ]; then
        do_showmsg "success" "log" "Uploading backup on Amazon Drive successfull"
        ret=$((${ret}+0))
else
        do_showmsg "error" "log" "Uploading backup on Amazon Drive return an error"
        ret=$((${ret}+1))
fi

rm -rf /backup

#########################
##  RETURN END SCRIPT  ##
#########################

# Add message on the log
if [ "${ret}" -eq "0" ]; then
        do_showmsg "success" "log" "Finish execution successful"
elif [ "${ret}" -eq "1" ]; then
        do_showmsg "warn" "log" "Finish execution with ${ret} error"
else
        do_showmsg "error" "log" "Finish execution with ${ret} errors"
fi

# Exit
exit ${ret}

Conclusion

Vous avez maintenant une façon de sauvegarder tous vos sites facilement avec un simple script. Nous trouvions aussi important de vous présenter la méthode que nous utilisons pour ce site.

7 Commentaires

  1. Merci pour cet exemple. J’ai créé de nombreux scripts dont 1 pour la sauvegarde avec les mêmes outils mais je ne connaissais pas les fonctions et je vais donc reprendre l’idée de ‘do_showmsg’ pour mettre de la couleur dans l’exécution de mes scripts. Par contre les ‘>> ${returnlog}’ dans la fonction ne renvoient forcément jamais rien dans le sdout. Je les ai remplacés par ‘| tee ${returnlog}’.

  2. Salute,

    Ne le prends pas mal mais je trouve ton script extrêmement lourd :
    – Quel intérêt à toutes les variables *_bin ? En général on met directement le chemin
    – Les parties « Création du dossier s’il n’existe pas » ne servent à rien hormis alourdir le script énormément mkdir -p veut justement dire tu crées le dossier si il n’existe pas et tu ne fais rien si il existe déjà bref le reste c’est alourdir inutilement
    – Starting backup all websites at /bin/date +%d/%m/%Y, /bin/date +%H:%M:%Sn –> echo /bin/date '+%d/%m/%Y, %H:%M:%S'
    – [[ -z $(which lftp) ]] && apt-get install lftp au pire pourquoi ne pas faire un bête apt-get -y install lftp gzip…

    Tcho !

LAISSER UN COMMENTAIRE

Merci d'entrer votre commentaire !
Merci d'entrer votre nom

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.