Резервное копирование сайтов в Яндекс Диск
Благодаря статье Михаила Воеводского заметил, что тема резервного копирования востребована в сообществе. Решил поделиться своим скриптом резервного копирования написанным на Python. Примечателен он тем, что
- Умеет удалять старые бекапы с ЯДиска, если они старее чем N дней (настраивается в config.yaml)
- Умеет удалять старые логи с сервера
- Раскладывает бекапы на ЯДиске по папкам вида: ГГГГ-ММ-ДД
- Бекапит системные папки: /etc/, /var/log/, /root/
В итоге, на Яндекс Диске, в папке для бекапов указанной в config.yaml, мы получаем список файлов, похожий на этот:
Не обращайте внимания на имена пользователей u1-u15 — это у меня на сервере панелька назначает их автоматически. Если вы называете пользователей в системе по-другому, то и на Яндекс Диске они будут называться также.
Примечание
Сервер обязательно должен быть настроен по этой инструкции:
- На каждый сайт создаётся свой пользователь в системе (1 сайт = 1 пользователь)
- Все сайты-пользователи располагаются в /var/www/
- Имя пользователя сайта, название и имя пользователя БД одинаковые
Инструкция по установке в Linux Ubuntu, Debian и т.п.
У вас уже должен быть установлен на сервере Python 3.
- Устанавливаем менеджер пакетов для Python 3:
apt-get install python3-pip
- Устанавливаем пакеты для Python, от которых зависим скрипт:
pip3 install requests pip3 install pyyaml
- Закидываем папку с бекапером куда-нибудь на сервер, например в /root/scripts/py/
- Настраиваем config.yaml. В конфиге указывается:
- Имя/пароль mysql root
- Имя/пароль от Яндекс Диска
- Временная папка, в которую закидывать бекапы на сервере
- Папка на Яндекс Диске, где будут лежать бекапы
- Что бекапить (системные папки, базу, файлы)
- Удалять ли старые логи
- Сколько дней хранить бекапы на Яндекс Диске (более старые будут удаляться)
- Вызываем
и прописываем ежедневный запуск в 2 часа ночи:sudo crontab -e
0 2 * * * /usr/bin/env python3 /root/scripts/py/YaDiskBackuper/backuper.py
Вот собственно и всё. Теперь вы можете запустить скрипт и проверить, корректно ли он работает. В консоли от рута запускаем:
sudo python3 /root/scripts/py/YaDiskBackuper/backuper.py
Замените путь до скрипта на свой.На сервере заходим во временную папку с бекапами, заходим на Яндекс Диск и наблюдаем, появляются ли там файлы.
Поблагодарить автора
Отправить деньги
Комментарии: 22
Привет! Попробовал. При запуске руками из консоли через пару секунд увидел сообщение «Enter password:».
Проверил пароли, вроде все верно… Это к чему запрос относится? Файлы, кстати, на Яндекс.Диск начали появляться… логи и папка etc по крайней мере :)
Проверил пароли, вроде все верно… Это к чему запрос относится? Файлы, кстати, на Яндекс.Диск начали появляться… логи и папка etc по крайней мере :)
Привет! Странно, сейчас проверил у себя, запроса нет. Может пароль от root юзера просит? Потому что в скриптах такого запроса нет.
А файлы сайтов и базы появились на Яндекс Диске?
А файлы сайтов и базы появились на Яндекс Диске?
Да, они начали появляться, правда я потом консоль закрыл и все остановилось :)
Решил подождать пока сработает крон…
Решил подождать пока сработает крон…
Можно сделать проще без установки питонов
Как на счёт подробностей?
По моему лучше было бы загрузить пакет в pypi и сделать скрипт исполняемым, чтобы не мучатся. Ну и провести рефакторинг чтобы все работало на python 2, тогда сразу на любой версии ubuntu можно будет запускать. Ну и исправить нейминг :) уже давно не видел кэмэлкейс в именах файлов и модулей, а лучше просто добавить этот пакет который вы используете как зависимость
Покажи, как надо, пожалуйста, в соседнем топике.
Ну показывать если честно лень, для себя мне это не нужно учитывая что есть официальный консольный ЯД, и таки вещи по мне проще реализовать на bash. Но решение имеет право на жизнь и каждый пункт можно легко реализовать с помощью гугла, пофакту нужно просто настроить все в setup.py прри формирования пакетаю
Привет!
Есть небольшая проблемка, не сохраняются бекапы баз, файлы все ок, а вот баз нет.
Пароль в конфиге root пользователя проверил 3-ды, верный.
Куда еще посмотреть можно?..
Есть небольшая проблемка, не сохраняются бекапы баз, файлы все ок, а вот баз нет.
Пароль в конфиге root пользователя проверил 3-ды, верный.
Куда еще посмотреть можно?..
Можно попробовать вручную подобную операцию проделать в терминале сервера:
mysqldump --skip-lock-tables -u[[+mysqlUser]] -p[[+mysqlPassword]] [[+dbName]] | bzip2 -c > filename.sql.bz2
Попробовал, увидел ошибку… связанную с тем, что мой пароль начинается с символа "&", экранирует ли скрипт пароль при выполнении команды? Может быть в этом дело?, см. superuser.com/questions/123928/escaping-a-password-using-mysqldump-console
Ну а сама команда, когда я заключил пароль в кавычки, выполнилась успешно.
Об этом речь? — github.com/gvozdb/YaDiskBackuper/commit/45dc46e5967b99a4322c74a129573e9c1c019661
Сообщи, пожалуйста, когда проверишь скрипт.
Сообщи, пожалуйста, когда проверишь скрипт.
Да, про это.
Бекапы раз в неделю)
Сообщу позже, если не забуду)))
Бекапы раз в неделю)
Сообщу позже, если не забуду)))
Сталкивался ли кто-нибудь с ошибкой выполнения скрипта?
Есть 2 сервера на Ubuntu 16.04.1, настроенные аналогично, отличия в них:
1) На площадке Flops с установленной по умолчанию системой для работы в облаке
2) Выделенный сервер на другой площадке с системой, установленной из официального образа
В первом случае скрипт создания бэкапов вываливается с ошибками, во втором работает без запинки.
На обоих серверах python3 версии 3.5.1-3, модуль requests версии 2.13.0.
Вывод ошибок:
Поскольку Питон не знаю от слова совсем, отладка превращается почти в метод научного тыка. Понимаю лишь общую логику выполнения, не более того.
Надеюсь на помощь более опытных в Питоне товарищей.
Есть 2 сервера на Ubuntu 16.04.1, настроенные аналогично, отличия в них:
1) На площадке Flops с установленной по умолчанию системой для работы в облаке
2) Выделенный сервер на другой площадке с системой, установленной из официального образа
В первом случае скрипт создания бэкапов вываливается с ошибками, во втором работает без запинки.
На обоих серверах python3 версии 3.5.1-3, модуль requests версии 2.13.0.
Вывод ошибок:
# python3 /root/scripts/py/YaDiskBackuper/backuper.py
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/requests/utils.py", line 792, in check_header_validity
if not pat.match(value):
TypeError: expected string or bytes-like object
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/root/scripts/py/YaDiskBackuper/backuper.py", line 72, in <module>
disk.ls( path_webdav_today )
File "/root/scripts/py/YaDiskBackuper/YaDiskClient/YaDiskClient.py", line 83, in ls
resp = self._sendRequest("PROPFIND", path, {'Depth': 1})
File "/root/scripts/py/YaDiskBackuper/YaDiskClient/YaDiskClient.py", line 54, in _sendRequest
return s.send(req.prepare())
File "/usr/local/lib/python3.5/dist-packages/requests/models.py", line 257, in prepare
hooks=self.hooks,
File "/usr/local/lib/python3.5/dist-packages/requests/models.py", line 303, in prepare
self.prepare_headers(headers)
File "/usr/local/lib/python3.5/dist-packages/requests/models.py", line 443, in prepare_headers
check_header_validity(header)
File "/usr/local/lib/python3.5/dist-packages/requests/utils.py", line 796, in check_header_validity
"not %s" % (value, type(value)))
requests.exceptions.InvalidHeader: Header value 1 must be of type str or bytes, not <class 'int'>
Поддержка Flops ничего существенного, естественно не говорит, ибо речь идет не только о стандартном ПО из пакетов.Поскольку Питон не знаю от слова совсем, отладка превращается почти в метод научного тыка. Понимаю лишь общую логику выполнения, не более того.
Надеюсь на помощь более опытных в Питоне товарищей.
После очередного обновления системы, стала появляться такая же ошибка.
Проанализировав логи, оказалось, что данный скрипт не работает с модулем requests версии 2.13.
Помог откат модуля до версии 2.10
Проанализировав логи, оказалось, что данный скрипт не работает с модулем requests версии 2.13.
Помог откат модуля до версии 2.10
pip3 install requests==2.10
Семен, огромное спасибо!
Павел, привет.
А можно спросить совета о доработке, как выкинуть из бекапа некоторые жестко прописанные директории?
У меня есть сайт (среди десятков других на сервере), где имеется фото архив на несколько Гб, не хочу его бекапить каждый раз. Как бы прописать эту директорию в игнор? Т.е. сам сайт пусть идет в бекап, но без этой директории с фотографиями.
А можно спросить совета о доработке, как выкинуть из бекапа некоторые жестко прописанные директории?
У меня есть сайт (среди десятков других на сервере), где имеется фото архив на несколько Гб, не хочу его бекапить каждый раз. Как бы прописать эту директорию в игнор? Т.е. сам сайт пусть идет в бекап, но без этой директории с фотографиями.
На самом деле особо великой сложности нет. Я бы создал файлик в корне юзера, в котором бы указывалось, какие папки исключать при запаковке, в формате: 1 строка — 1 директория. А на стороне бекапера получал бы содержимое этого файла и передавал необходимые параметры (--exclude="") в tar.
Благодарю за наводку!
Теперь с питоном разобраться бы)
Теперь с питоном разобраться бы)
Traceback (most recent call last):
File "/root/scripts/py/YaDiskBackuper/backuper.py", line 30, in <module>
config = yaml.load( config_f )
File "/usr/local/lib/python3.5/dist-packages/yaml/__init__.py", line 70, in load
loader = Loader(stream)
File "/usr/local/lib/python3.5/dist-packages/yaml/loader.py", line 34, in __init__
Reader.__init__(self, stream)
File "/usr/local/lib/python3.5/dist-packages/yaml/reader.py", line 85, in __init__
self.determine_encoding()
File "/usr/local/lib/python3.5/dist-packages/yaml/reader.py", line 135, in determine_encoding
self.update(1)
File "/usr/local/lib/python3.5/dist-packages/yaml/reader.py", line 169, in update
self.check_printable(data)
File "/usr/local/lib/python3.5/dist-packages/yaml/reader.py", line 144, in check_printable
'unicode', "special characters are not allowed")
yaml.reader.ReaderError: unacceptable character #x009f: special characters are not allowed
in "/root/scripts/py/YaDiskBackuper/config.yaml", position 118
Была вот такая ошибка из-за русских коментов в файле config.yaml, может версия у меня старая, не знаю
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.