Друзья, всем привет!
Помимо основной работы инженером данных, я поддерживаю небольшой сайт на Django (посвящен информационным материалам по преподаванию истории и обществознания).
Так как материалы на сайт добавляются довольно часто, а также регистрируются новые пользователи, конечно же возникла идея, как бы правильно организовать бэкап базы данных - чтобы я мог легко синхронизировать данные на сервере с данными, лежащими в базе на рабочем компьютере.
Сразу скажу, что такой подход подойдет для баз, размер которых не является астрономическим (сотни гигабайт), в моем случае база весит всего 50 Мб, статика около 400 - поэтому мне не составляло большого труда синхронизировать такие объемы. Думаю, небольшие и даже средние интернет магазины и блоги вряд ли хранят на порядки больше данных.
Для больших проектов, лучше бэкапы архивировать, шифровать и отправлять куда нибудь в s3 типа Minio.
Когда новая инфа на сайте появлялась довольно редко, я все делал руками, а именно:
заходил на удаленный сервер, где крутится сайт, по ssh
выполнял команду для создания полной копии БД
sudo -u postgres pg_dumpall -c -f {remote_db_copy_file_path
потом переключался в терминал ос рабочего ноута, создавал папку с названием, соответствующем дате бэкапа
с помощью утилиты scp, копировал с удаленной машины с сайтом бэкап, полученный в пункте 2 - т.е. типа такой команды
scp -r {remote_user}@{remote_host}:{remote_media_path} {local_media_full_path}
опять же с помощью scp копировал статику с файлами из папки
удалял файл бэкапа из папки на удаленном сервере
У такого подхода главный минус - это потраченное время, а также возможная путаница с названиями скопированных файлов и папок.
Поэтому настал час, когда я решил автоматизировать свою работу и написал скрипт на Python, автоматизирующий рутину по созданию бэкапа.
Сам скрипт лежит вот здесь, в моем GitHub, скачивайте и пользуйтесь.
Давайте более подробно рассмотрим, как он работает:
Делается подключение по ssh с помощью библиотеки paramiko, сделал с помощью файла rsa-key, который paramiko ищет автоматом, соответственно пароль указывать не надо
В скрипте за подключение отвечает функция _initialize_ssh_client
Получаем название файла с копией БД, которую необходимо будет создать, с помощью функции _get_db_copy_remote_filename. Принцип простой, берем текущее время и дату, и подставляем в название файлика, получается что то типа “01072023_155045.sql". К этому имени подставится путь, взятый из переменной окружения REMOTE_DBCOPY_FOLDER
Похожим образом задаются переменные, чтобы понимать, куда потом надо сложить на локальной машине копию базы, и как назвать папку для копии статических файлов. Т.е. это маленькие функции _get_db_copy_full_path и _create_local_media_folder, тоже работающие с переменными окружения
Функция make_db_backup собственно делает сам бэкап, через команду pg_dumpall, предварительно выдав права юзеру postgres на папку, куда положится бэкап
Бэкап грузится на локальную машину (upload_db_backup_to_local_machine)
Старые бэкапы удаляются с сервера (delete_old_copies_on_remote). Важно отметить, что срок актуальности бэкапа в днях можно задать в конфиге через переменную old-db-copies-exp-period. Потом данный период подставится в команду утилиты find.
Ну и в конце, функция copy_media_files_to_local перекачивает статику с сервера на локальную машину
С алгоритмом работы понятно, теперь давайте распишу, что вам надо сделать, чтобы у Вас тоже все запустилось и работало,
Иметь интерпретатор питона на локальной машине
Скачать репозиторий с моего гитхаба https://github.com/Riddik1993/DB-and-static-copy-from-remote
Настроить с Вашим удаленным сервером вход по ssh не по паролю, а по ключу из файла. Как это сделать - есть много туториалов в статьях и на ютубе, я сам научился по видео на канале Диджитализируй.
Также это стоит сделать и не только ради скрипта с копированием базы, но и просто из соображений безопасности - так как по паролю ваш сервер гораздо легче взломать чем через ключ rsa
Находясь в папке скаченного репозитория, вводим в терминале команду pip install requirements.txt и ставим нужные для скрипта зависимости. Если не хотите ставить их глобально, но создайте виртуальное окружение сначала и ставьте туда
Обращаем внимание на файл config.conf. Надо создать переменные окружения, которые указаны внутри фигурных скобок - это можно сделать, отредактировав файл ~/.bashsrc
Просто открываем этот файлик, добавляем строчки такого формата
export REMOTE_USER=”username”
Сохраняем, вводим команду
Если совсем нет времени это делать, можно конечно и прямо в этот файл задать, паролей там никаких нет, но палить параметры напрямую в коде - это конечно плохо, все же через переменные безопасней.
Когда все сделано, в терминале в папке репозитория запускаем команду python3 make_db_media_copy.py
В выводе вы увидите логирование всех стадий работы скрипта.
Файл с копией базы положился в папку, название которой хранится в переменной LOCAL_DBCOPY_PATH
Медиафайлы положились в папку, которую скрипт предварительно создал, в указанной нами директории LOCAL_MEDIA_PATH
Если что то упало - в принципе будет ясно почему (смотри скриншот с логами). Но если что. пишете в комментариях - всегда рад помочь)
Также пишите, как делаете логирование Вы)
Если понравилось, буду рад приветствовать вас в своем телеграм канале, куда публикую интересные обзоры питон-функций, разборы задачек с собеседований, ну и просто интересные мысли.