
Бэкап (backup — «резервная копия»), — это создание копии данных, хранящихся на устройстве, с целью возможности их восстановления в случае потери или повреждения оригиналов. Бэкапы делаются для файлов, папок, приложений, систем и других данных. Обычно провайдеры предоставляют возможность снятие полного снапшота (snapshot) VPS сервера. Такой вариант бэкапа хорош, но не позволяет полученные данные загрузить себе локально на ПК или один-в-один перенести на другой сервер. Можно установить специализированное ПО, но оно занимает место на диске и потребляет дополнительный объем памяти. И обычно, хорошие системы резервного копирования стоят немалых денег, а бесплатные, не обладают нужной гибкостью и функциональностью. Поэтому предлагается простой bash-скрипт без overhead, позволяющий создавать резервные копии: файлов, папок, volumes Docker контейнеров, баз данных и т.д.
Bash-скрипт рассчитан на запуск в ОС Ubuntu, позволяет создавать резервные копии следующих типов данных:
- Файлов;
- Папок;
- Отдельных volume (том) Docker контейнеров на горячую (без остановки работы самих контейнеров);
- Отдельных volume (том) Docker контейнеров с остановкой самих контейнеров (когда может быть нарушена целостность данных, например базы данных);
- Базы данных MariaDB и PostgreSQL;
- Список cron-задач;
- Настройки UFW;
- Настройки Fail2ban.
Bash-скрипт обладает следующими достоинствами:
- Не требует установки;
- Нет overhead, только базовые операции копирования и сжатия данных;
- Легко модифицируется;
- Легко добавить как cron-задачу;
- Не требует обновлений;
- Работает молча, не просит ни пить, ни кушать.
Все данные упаковываются с помощью утилиты RAR (бесплатная) для максимального сжатия данных. Вначале, данные с сохранение файловой структуры архивируются в формат .tar, затем по возможности, без локального сохранения через pipe механизм, передаются в утилиту rar для получения конечного архива. Если pipe механизм не используется, то создается .tar архив на диске, затем он упаковывается в формат .rar. Для минимизации простоя Docker контейнеров, для которых требуется остановка, после остановки формируются только .tar архивы, затем запускаются контейнеры. А после запуска всех контейнеров, выполняется сжатие volumes в формат .rar.
Система резервного копирования состоит из трех файлов:
- b1_backup_server2.sh — скрипт, выполняющий резервное копирование;
- b1_backup_server2_vars.sh — скрипт с настройками объектов резервного копирования;
- b2_backup_upload_mega.nz.sh — скрипт для загрузки резервной копии на MEGA.NZ (необязателен).
Скрипт с настройками объектов резервного копирования — b1_backup_server2_vars.sh
Для настройки объектов резервного копирования требуется править только скрипт — b1_backup_server2_vars.sh. Скрипт содержит переменные, декларируемые как массив.
Переменные:
Файлы и папки
- listfilestobackup — список файлов для архивирования, перечисляются построчно, каждый файл на отдельной строке.
declare listfilestobackup=" /etc/hostname /etc/hosts /etc/environment /etc/docker/daemon.json"
В подобном стиле задаются и другие переменные.
- listfolderstobackup — список папок для архивирования.
Volumes (тома) Docker контейнеров
Без остановки контейнеров (на горячую).
- listvolumestobackup — названия Docker volumes (тома, название папок) для архивирования на горячую.
Например, volumes контейнеров хранятся по пути /var/lib/docker/volumes/ , и располагаются по путям:
- /var/lib/docker/volumes/gotify-data
- /var/lib/docker/volumes/pihole-config
- /var/lib/docker/volumes/pihole-dnsmasq-config
Соответственно, переменная listvolumestobackup должна содержать следующие данные:
declare listvolumestobackup=" gotify-data pihole-config pihole-dnsmasq-config"
С остановкой контейнеров.
Некоторые данные, могут быть повреждены, если копирование выполняется на горячую, например, это относится к таким СУБД как MariaDB и PostgreSQL. Вначале необходимо остановить контейнеры, использующие базы данных (например, Matomo), затем останавливаются контейнеры с СУБД (MariaDB и PostgreSQL), выполняется резервное копирование volumes в формат .tar, и в завершение запускаются контейнеры, которые были остановлены. После запуска контейнеров, выполняется сжатие .tar архивов в формат .rar.
- listdbcontainersforstopping — содержит список контейнеров, которые необходимо остановить до резервного копирования volumes, остановка выполняется в порядке очереди от первого до последнего. Контейнер matomo_local подключается к СУБД MariaDB (контейнер some-mariadb), контейнер wallabag_local подключается к СУБД PostgreSQL (контейнер some-postgres). Выполняется остановка контейнеров в следующем порядке: matomo_local > wallabag_local > some-mariadb > some-postgres.
declare listdbcontainersforstopping=" matomo_local wallabag_local some-mariadb some-postgres"
Соответственно, после резервного копирования контейнеры запускаются в обратном порядке. Переменная listdbcontainersforstart (не требуется изменять) содержит обратный список listdbcontainersforstopping. Запуск контейнеров выполняется в следующем порядке: some-postgres > some-mariadb > wallabag_local > matomo_local.
- listdbvolumestobackup — названия Docker volumes (тома, название папок), которые архивируются с остановкой Docker контейнеров, указанных в listdbcontainersforstopping. В этом списке нет volumes контейнеров matomo_local и wallabag_local, т.к. они не содержат оперативные данные необходимые для сохранения. Однако, их присутствие в списке остановки контейнеров объясняется зависимостью от работы контейнеров some-mariadb и some-postgres, из-за использования баз данных.
declare listdbvolumestobackup=" some-mariadb-data some-postgres-data"
Базы данных MariaDB и PostgreSQL в формат SQL
Помимо копирования volumes СУБД, так же доступно создание резервных копии баз данных средствами самих СУБД. Выполняется резервное копирование указанных баз данных с ролями (пользователями) СУБД.
Настройки доступа к СУБД MariaDB:
declare mariadb_host="172.15.1.30" declare mariadb_user="root" declare mariadb_password="password"
- listnamesmariadb — названия баз данных MariaDB для резервного копирования.
Настройки доступа к СУБД PostgreSQL:
declare postgres_host="172.15.1.31" declare postgres_user="postgres" declare postgres_password="password"
- listnamespostgres — названия баз данных PostgreSQL для резервного копирования
Скрипт резервного копирования — b1_backup_server2.sh
Основной скрипт запуска выполнения резервного копирования — b1_backup_server2.sh.
Для работы скрипта требуется установить утилиты tar , rar и клиентов работы с СУБД MariaDB и PostgreSQL.
Установка необходимых утилит:
sudo apt update && sudo apt install tar rar mariadb-client # PostgreSQL client 17 sudo apt update && sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg sudo apt update && sudo apt install postgresql-client-17
Запуск скрипта:
chmod +x b1_backup_server2.sh sudo MIN_FREE_SPACE=1500 ./b1_backup_server2.sh --name srv1-dc-spb1-timeweb_ --vars b1_backup_server2_vars.sh --source_volumes /var/lib/docker/volumes/ --destination /var/backup/
Аргументы:
1) MIN_FREE_SPACE — свободное дисковое пространство в MiB, необходимое для размещения резервной копии. Если меньше, то выполнение скрипта приостанавливается;
2) name — название префикса архива;
3) vars — путь к конфигурационному файлу b1_backup_server2_vars.sh ;
4) source_volumes — путь к папке с volumes для Docker контейнеров;
5) destination — путь сохранения результирующего архива.
По итогу выполнения скрипта, резервная копия будет расположена в папке с названием, например:
srv1-dc-spb1-timeweb_24_06_2025_14-53 .Папка с резервной копией данных, содержит следующую структуру:
anton@srv1-dc-spb1-timeweb:/var/backup$ tree . └── srv1-dc-spb1-timeweb_24_06_2025_14-53 ├── crontab.bak ├── databases │ ├── mariadb-dump_matomo.sql.rar │ ├── mariadb-dump_testdb.sql.rar │ ├── mysqldump_grants.sql.rar │ ├── pg_dump_testdb.sql.rar │ ├── pg_dump_wallabag.sql.rar │ └── pg_dumpall_roles-only.sql.rar ├── fail2ban.tar.rar ├── files.tar.rar ├── folders.tar.rar ├── ufw.tar.rar └── volumes ├── gotify-data.tar.rar ├── pihole-config.tar.rar ├── pihole-dnsmasq-config.tar.rar ├── some-mariadb-data.tar.rar └── some-postgres-data.tar.rar 4 directories, 16 files
Аргументы утилиты RAR
В отличие от zip, алгоритм rar более требователен к вычислительным ресурсам, степень сжатия регулируется переменной RAR_COMMAND, скрипт b1_backup_server2.sh . Аргументы для утилиты rar :
# rar # rr[N] - Add data recovery record # m<0..5> Set compression level (0-store...3-default...5-maximal) # v.. volume size declare RAR_COMMAND="-rr5 -m3 -v307200k"
Аргументы:
1) rr — добавляет данные для восстановления архива на случай повреждения, задается в процентном выражение от всего размера архива;
2) m — степень сжатия от 0 до 5. В случае наличия производительного vCPU на VPS сервере, выставьте значение от 3 до 5;
3) v — размер архива, если размер файла архива превысит 300 MB, то архив поделится на n-ое количество файлов, и станет многотомным.
Теперь полученную резервную копию можно загрузить в хранилище MEGA.NZ. По правилам резервного копирования, копию данных нельзя хранить на том же узле, где находятся исходные данные.
Скрипт загрузки данных в MEGA.NZ — b2_backup_upload_mega.nz.sh
Используется для загрузки данных в хранилище MEGA.NZ — b2_backup_upload_mega.nz.sh.
Для работы требуется предварительно установить утилиту MEGA CMD. Для установки MEGA CMD выполните следующий скрипт:
sudo apt update && sudo apt install wget wget https://mega.nz/linux/repo/xUbuntu_24.04/amd64/megacmd-xUbuntu_24.04_amd64.deb sudo apt install "$PWD/megacmd-xUbuntu_24.04_amd64.deb" && rm "$PWD/megacmd-xUbuntu_24.04_amd64.deb"
Запуск скрипта:
chmod +x b2_backup_upload_mega.nz.sh ./b2_backup_upload_mega.nz.sh --login user@server.com --password PASSWORD --source /var/backup/ --destination /folder_on_mega/
Аргументы:
1) login — логин авторизации.
2) password — пароль учетной записи.
3) source — путь к папке, которую необходимо загрузить в хранилище MEGA.NZ.
4) destination — путь в самом хранилище MEGA.NZ, по которому будет расположен архив.
Так же, вы можете воспользоваться другим инструментами для загрузки архива в другие хранилища.
Структура скрипта — b1_backup_server2.sh
Все задачи выполнения резервного копирования вынесены в отдельные функции, которые можно произвольно изменять, добавлять новые или исключать, принцип максимальной открытости.
Основное тело выполнения скрипта:
echo "================= Start backup =================" # script execution start time START_TIME=$(date +%s) echo "Start is: $(date)" echo "Folder: ${FULL_PATH_BACKUP_DESTINATION}" echo "----------------------------------------------" echo "" funcBackupFiles funcBackupFolders funcBackupVolumes funcBackupDatabasesMariaDB funcBackupDatabasesPostgreSQL funcBackupDatabaseCompression funcBackupDatabasesWithContainerStop funcBackupCrontab funcBackupUfw funcBackupFail2ban echo "================= End backup ================="
В фрагменте перечислены названия вызываемых функций. Например, если нет необходимости выполнять резервное копирования баз данных MariaDB, то достаточно удалить строку с вызываемой функцией funcBackupDatabasesMariaDB.
Если у вас несколько экземпляров СУБД MariaDB, то вам следует создать отдельные файлы b1_backup_server2_vars.sh , в которые необходимо прописать разные реквизиты доступа к экземплярам СУБД MariaDB.
Создания сron задачи для регулярного выполнения скрипта резервного копирования
Создадим cron задачу для ежедневного создания резервной копии данных, во время наименьшей нагрузки на VPS сервер, в 02:05. Разместим bash-скрипты в каталоге /var/scripts/ . Допустим, в системе создана учетная запись с именем user_backup, от имени которой, необходимо выполнить скрипт резервного копирования.
Выставим необходимые права:
sudo chown -R user_backup:user_backup /var/scripts/{b1_backup_server2.sh,b1_backup_server2_vars.sh,b2_backup_upload_mega.nz.sh} sudo find /var/scripts/ -type f -exec sudo chmod 644 {} + sudo chmod 755 /var/scripts/*.sh /var/scripts/*.csx
Откроем список cron задач:
sudo crontab -e
Если cron не установлен в системе, то необходимо выполнить команду для установки:
sudo apt update && sudo apt install cron && sudo systemctl enable cron && sudo systemctl status cron
Добавим строку в самый конец:
# At 02:05 5 02 * * * sudo -u user_backup MIN_FREE_SPACE=1500 /var/scripts/b1_backup_server2.sh --name srv1-dc-spb1-timeweb_ --vars /var/scripts/b1_backup_server2_vars.sh --source_volumes /var/lib/docker/volumes/ --destination /var/backup/ && sleep 10 && /var/scripts/b2_backup_upload_mega.nz.sh --login user@server.com --password PASSWORD --source /var/backup/ --destination /folder_on_mega/
Для выставления другого расписания выполнения задачи, воспользуйтесь сайтом Crontab.guru — The cron schedule expression generator.
Сохраним изменения и перезапустим службу:
sudo systemctl restart cron sudo systemctl status cron
Если необходимо сохранить вывод исполнения скрипта очистки, то необходимо указать следующий формат исполнения cron задачи:
# At 02:05 5 02 * * * sudo ... >> /var/log/backup.log 2>&1
Где >> /var/log/backup.log — вывод будет записан в лог-файл доступный для просмотра.
Для просмотра журнала исполнения скрипта выполнить команду:
cat /var/log/backup.log
Ресурсы
Скрипты резервного копирования — GitHub devdotnetorg/Linux.
* — титульная иллюстрация к посту сгенерирована системой ChatGPT.