Иногда возникает задача - настроить автоматический бекап сайтов (файлов и базы) на удаленный сервер, для сервера, на котором стоит Битрикс Веб-окружение.
К сожалению в штатной поставке механизм бекапов довольно урезанный (можно бекапить только основной сайт и один дополинетльный, и только на текущем сервере), поэтому, можно написать небольшой скриптик, который будет делать нужную нам задачу:
Для этого создаем в папке /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-х - то удаляются старые бекапы.
Дополнительные фишки, которые можно при необходимости настроить:
- архивирование бекапа (сейчас в скрипте настроено без архивирования, для снижения нагрузки на процессор)
- шифрование бекапа
- подключение к удаленному серверу по ключу (а не по паролю)
- хранение бекапов за первые числа последних двух месяцев, последних недель, и дней