Иногда возникает задача - настроить автоматический бекап сайтов (файлов и базы) на удаленный сервер, для сервера, на котором стоит Битрикс Веб-окружение.
К сожалению в штатной поставке механизм бекапов довольно урезанный (можно бекапить только основной сайт и один дополинетльный, и только на текущем сервере), поэтому, можно написать небольшой скриптик, который будет делать нужную нам задачу:
Для этого создаем в папке /home/bitrix/backup/ файл backup.php с таким содержанием:
То есть, мы создаем php-скрипт, который будет запускаться из командной строки.
Меняем в скрипте переменные $server, $login и $passw, указав данные для подключения к удаленному серверу, на котором будем хранить бекапы. Подключение будет происходить по ssh.
Ставим права на запуск к файлу
chmod +x /home/bitrix/backup/backup.php
и запускаем
/home/bitrix/backup/backup.php
Если рукается на ошибки вроде "No such file or directory или bad interpreter" - проверьте, что у вас файл сохранен в кодировке Unix.
Если возникает ошибка отправки на удаленный сервер - то проверьте, установлен ли у вас модуль php-pecl-ssh2
yum install php-pecl-ssh2
чтобы повесить это на крон - добавим в файлик /etc/crontab строчку
# backup every day at 02:00
0 2 * * * bitrix /usr/bin/php -f /home/bitrix/backup/backup.php >/dev/null 2>&1
Принцип работы скрипта
Скрипт следует применять, если у вас все сайты размещаются в директории ext_www (то есть, работают как дополнительные сайты). Это полезно, например, если вы используете Битрикс Веб Окружение для хостинга множества сайтов.
Скрипт проходится по папкам директории /home/bitrix/ext_www/ (то есть, по сайтам), находит в них файлы /bitrix/php_interface/dbconn.php , берет из них данные для подключения к базе, и бекапит базу через mysqldump в папку /bitrix/backup/ текущего сайта.
Потом скрипт бекапит файлы сайта, исключая папки с кешем, папку с временными файлами и папку с бекапами, после чего добавляет в этот архив бекап mysql (который в папке /bitrix/backup/, сохраняя путь к этому файлу). Такая структура используется для того, чтобы была совместимость с логикой создания Битрикс-бекапов, то есть, данный бекап можно легко развернуть с помощью стандартного restore.php
Бекап сайта сохраняется в папке /home/bitrix/backup/archive/ на данном сервере.
Но просто так хранить бекап у себя на сервере не интересно, так как лучше всего чтобы они отсылались на удаленный сервер, а с этого сервера удалялись, это и надежнее, и сервера можно подобрать соответствующей конфигурации. Поэтому, наш php-скрипт отсылает бекап на удаленный сервер, и удаляет его с текущего сервера. Для каждого сайта на удаленном сервере создается своя папка, и в нее складываются бекапы по каждому сайту.
Если бекапов на удаленном сервере больше 3-х - то удаляются старые бекапы.
Дополнительные фишки, которые можно при необходимости настроить:
- архивирование бекапа (сейчас в скрипте настроено без архивирования, для снижения нагрузки на процессор)
- шифрование бекапа
- подключение к удаленному серверу по ключу (а не по паролю)
- хранение бекапов за первые числа последних двух месяцев, последних недель, и дней
К сожалению в штатной поставке механизм бекапов довольно урезанный (можно бекапить только основной сайт и один дополинетльный, и только на текущем сервере), поэтому, можно написать небольшой скриптик, который будет делать нужную нам задачу:
Для этого создаем в папке /home/bitrix/backup/ файл backup.php с таким содержанием:
#!/usr/bin/php <?php $sitesPath = "/home/bitrix/ext_www"; // Путь, где лежат сайты $backupDir = "/home/bitrix/backup/archive"; // Путь к временной папке с бекапами на сервере с сайтами $externalBackupDir = "/mnt/3t/web-backups"; // Путь к папке где будут лежать бекапы на удаленном сервере // Отправляем бекапы на удаленный сервер // понадобится установка модуля (CentOS) // yum install php-pecl-ssh2 $server = '123.123.123.123'; // ай-пи адрес сервера, куда будем бекапить $login = "bxbackup"; // логин пользователя на удаленном сервере $passw = "*******"; // пароль пользователя // Получаем список сайтов $strExec = "cd ".$sitesPath."; ls"; exec($strExec, $arSites, $errRez); if (!empty($arSites)) { foreach ($arSites as $site) { // Текущий сайт, который бекапим $_SERVER["DOCUMENT_ROOT"] = "/home/bitrix/ext_www/".$site; if (is_dir($_SERVER["DOCUMENT_ROOT"])) { // Уведомление для пользователя echo "\033[37;1;41m starting backup ".$site."\033[0m\n"; // Делаем бекап базы, сохраняем в папку /bitrix/backup/ в каждом сайте $backupDate = date('Ymd').'_'.date('His'); echo "doing base backup... "; unset($DBLogin); unset($DBPassword); unset($DBName); include($_SERVER["DOCUMENT_ROOT"]."/bitrix/php_interface/dbconn.php"); // Создадим папку для бекапов (если её нету) if (!is_dir($_SERVER["DOCUMENT_ROOT"].'/bitrix/backup/')) { mkdir($_SERVER["DOCUMENT_ROOT"].'/bitrix/backup/'); } // Делаем дамп базы в папку с бекапами $strExec = 'mysqldump -u'.$DBLogin.' -p'.$DBPassword.' '.$DBName.' > '.$_SERVER["DOCUMENT_ROOT"].'/bitrix/backup/'.$backupDate.'_'.$DBName.'.sql'; exec($strExec, $arRez, $errRez); if ($errRez == 0) echo "done\n"; else echo "error :(\n"; //=======================// // Создадим бекап файлов // //=======================// echo "doing files backup... "; // Путь к файлу бекапа $backupPath = $backupDir."/".$backupDate.'-'.$site.'.tar'; // Маска исключения $arExclude = array( "bitrix/backup", "bitrix/cache", "bitrix/managed_cache", "bitrix/stack_cache", "bitrix/local_cache", "bitrix/tmp", "upload/tmp", "upload/resize_cache", ); $strExclude = " "; foreach ($arExclude as $ex) $strExclude .= "--exclude=".$ex." "; // Бекапим файлы $strExec = 'tar -cf '.$backupPath.' -C '.$_SERVER["DOCUMENT_ROOT"].' '.$strExclude.' . '; exec($strExec, $arRez, $errRez); // Дополнительно бекапим mysql файл $mysqlBackup = 'bitrix/backup/'.$backupDate.'_'.$DBName.'.sql'; // Добавляем в архив файлов бекапы базы $strExec = 'tar -rf '.$backupPath.' -C '.$_SERVER["DOCUMENT_ROOT"].' '.$mysqlBackup; exec($strExec, $arRez, $errRez); if ($errRez == 0) echo "done\n"; else echo "error :(\n"; // Удалим временный бекап с базой unlink($_SERVER["DOCUMENT_ROOT"].'/bitrix/backup/'.$backupDate.'_'.$DBName.'.sql'); // Отправляем бекап на удаленный сервер $connection = ssh2_connect($server, 22); if (ssh2_auth_password($connection, $login, $passw)) { echo "sending backup... "; $sftp = ssh2_sftp($connection); // Создаем директорию, если её нет $statinfo = ssh2_sftp_stat($sftp, $externalBackupDir.'/'.$site); if (empty($statinfo)) { $rez = ssh2_sftp_mkdir($sftp, $externalBackupDir.'/'.$site); } $rez = ssh2_scp_send($connection , $backupPath, $externalBackupDir."/".$site."/".$backupDate."-".$site.".tar"); if ($rez) echo "done \n"; else echo "false \n"; // Если бекапов больше 3-х - удалим более ранние // находим все бекапы $arFiles = scandir('ssh2.sftp://'.$sftp.$externalBackupDir.'/'.$site); // удаляем устаревшие бекапы if (count($arFiles) > 4) { foreach ($arFiles as $strFile) { if ($strFile == "." || $strFile == "..") continue; // Находим сведения о файле //$statinfo = ssh2_sftp_stat($sftp, $externalBackupDir.'/'.$site."/".$strFile); //print_r($statinfo); // удаляем файл (первый по счету, самый старый) $rez = ssh2_sftp_unlink($sftp, $externalBackupDir.'/'.$site."/".$strFile); if ($rez) echo "deleted ".$strFile." \n"; else echo "not deleted\n"; break; } } } else { echo "error connecting to remote server... \n"; } // удалим текущий временный бекап echo "deleting temp backup... "; $rez = unlink($backupPath); echo ($rez)? "done\n" : "error\n"; // Пауза 5 секунд между бекапами echo "sleeping 5 sek ... \n"; sleep(5); } } } |
Меняем в скрипте переменные $server, $login и $passw, указав данные для подключения к удаленному серверу, на котором будем хранить бекапы. Подключение будет происходить по ssh.
Ставим права на запуск к файлу
chmod +x /home/bitrix/backup/backup.php
и запускаем
/home/bitrix/backup/backup.php
Если рукается на ошибки вроде "No such file or directory или bad interpreter" - проверьте, что у вас файл сохранен в кодировке Unix.
Если возникает ошибка отправки на удаленный сервер - то проверьте, установлен ли у вас модуль php-pecl-ssh2
yum install php-pecl-ssh2
чтобы повесить это на крон - добавим в файлик /etc/crontab строчку
# backup every day at 02:00
0 2 * * * bitrix /usr/bin/php -f /home/bitrix/backup/backup.php >/dev/null 2>&1
Принцип работы скрипта
Скрипт следует применять, если у вас все сайты размещаются в директории ext_www (то есть, работают как дополнительные сайты). Это полезно, например, если вы используете Битрикс Веб Окружение для хостинга множества сайтов.
Скрипт проходится по папкам директории /home/bitrix/ext_www/ (то есть, по сайтам), находит в них файлы /bitrix/php_interface/dbconn.php , берет из них данные для подключения к базе, и бекапит базу через mysqldump в папку /bitrix/backup/ текущего сайта.
Потом скрипт бекапит файлы сайта, исключая папки с кешем, папку с временными файлами и папку с бекапами, после чего добавляет в этот архив бекап mysql (который в папке /bitrix/backup/, сохраняя путь к этому файлу). Такая структура используется для того, чтобы была совместимость с логикой создания Битрикс-бекапов, то есть, данный бекап можно легко развернуть с помощью стандартного restore.php
Бекап сайта сохраняется в папке /home/bitrix/backup/archive/ на данном сервере.
Но просто так хранить бекап у себя на сервере не интересно, так как лучше всего чтобы они отсылались на удаленный сервер, а с этого сервера удалялись, это и надежнее, и сервера можно подобрать соответствующей конфигурации. Поэтому, наш php-скрипт отсылает бекап на удаленный сервер, и удаляет его с текущего сервера. Для каждого сайта на удаленном сервере создается своя папка, и в нее складываются бекапы по каждому сайту.
Если бекапов на удаленном сервере больше 3-х - то удаляются старые бекапы.
Дополнительные фишки, которые можно при необходимости настроить:
- архивирование бекапа (сейчас в скрипте настроено без архивирования, для снижения нагрузки на процессор)
- шифрование бекапа
- подключение к удаленному серверу по ключу (а не по паролю)
- хранение бекапов за первые числа последних двух месяцев, последних недель, и дней