基於 Docker 的 Django 容器化部署之三:定時備份,兩步實現服務器遷移

本文章爲原創內容,只發佈於本博客和 我的私人博客,轉載請註明,謝謝


項目源碼,歡迎 Fork 和 Star | 本人 Django 博客預覽


基於 DockerDjango 容器化部署教程分爲三部分,當前所在的是第三部分

Django 博客進行 Docker 容器化之後,所需要的就是定時備份功能,能夠將數據隨時遷移到任何地方,畢竟容器化進行部署需要的就是輕量和易用。

既然備份了就要能夠恢復數據,這樣在遷移的時候,就可以保證數據不會丟失。

看了這個教程,簡單幾個命令就可以實現無損遷移項目。

腳本

自己編寫的 shell 腳本 migrate.sh 功能:

  • 自動備份
  • 自動清理
  • 自動恢復
  • 自動設置備份規則
#!/bin/bash

mysql_db=hw_mysql
mysql_table=website
mysql_username=root
mysql_password=zhwei.cn
meida_dir=./django/media
backup_dir=./backup

backup_dir_date=${backup_dir}/`date +%Y-%m-%d`
backup_date=`date +%Y%m%d-%H%M`


if [ ! -n "$1" ] ;then
    echo -e "\nUsage: migrate [-b] [-c] [-r <*.sql.gz> <*.tar.gz>] [-t <\"0 3 * * *\">]\n"
    echo "  -b,   backup mysql and media"
    echo "  -c,   clean old-to-date backup"
    echo "  -r,   restore mysql and media"
    echo -e "  -t,   set cron schedule expressions\n"
fi


while getopts :bcr:t: opt

do
    case $opt in
        b)
        echo -e "\n-----  Current start Backup  -----"
        
        echo "1. mkdir backup filedir: ${backup_dir_date}"
        mkdir -p ${backup_dir_date}
        
        echo "2. Backup MySQL to ${backup_dir_date}"
        docker exec ${mysql_db} /usr/bin/mysqldump -u ${mysql_username} --password=${mysql_password} ${mysql_table} | gzip > ${backup_dir_date}/website-${backup_date}.sql.gz
        
        echo "3. Backup media to ${backup_dir_date}"
        tar -zcvf  ${backup_dir_date}/media-${backup_date}.tar.gz ${meida_dir}
        
        echo -e "-----  Backup Success!  -----\n"
        ;;
        c)
        echo -e "\n-----  Current start Clean  -----"
        
        echo "1. Remove old-to-date website-*.sql"
        find ${backup_dir} -mtime +1 -name "*.sql.gz" -exec rm -rf {} \;
        
        echo "2. Remove old-to-date media-*.tar.gz"
        find ${backup_dir} -mtime +1 -name "*.tar.gz" -exec rm -rf {} \;
        
        echo "3. Remove empty filedir"
        while [ "$(find ${backup_dir} -empty)" ]; do find ${backup_dir} -empty | xargs -i rm -r {}; done
        
        echo -e "-----  Clean Success!  -----\n"
        ;;
        r)
        backup_sql=$2
        backup_meida=$3
        
        echo -e "\n-----  Current start Restore  -----" 
        
        echo "1. Unzip ${backup_sql}"
        gzip -cd ${backup_sql} > ${backup_sql%.*} 
        
        echo "2. Restore MySQL Databases"
        cat ${backup_sql%.*} | docker exec -i ${mysql_db} /usr/bin/mysql -u ${mysql_username} --password=${mysql_password} ${mysql_table}
        
        echo "3. Restore Media File"
        tar -zxvf ${backup_meida}
        
        echo -e "-----  Restore Done!  -----\n"
        ;;  
        t)
        echo "
        $2$3$4$5$6 cd `pwd` && sh migrate.sh -b -c

        " >> /var/spool/cron/root
        echo "Like crontab -e. Set cron schedule expressions: $2$3$4$5$6"
        echo "Command:cd `pwd` && sh migrate.sh -b -c"
        ;;         
        ?)
        echo -e "\nUsage: migrate [-b] [-c] [-r <*.sql.gz> <*.tar.gz>] [-t <\"0 3 * * *\">]\n"
        echo "  -b,   backup mysql and media"
        echo "  -c,   clean old-to-date backup"
        echo "  -r,   restore mysql and media"
        echo -e "  -t,   set cron schedule expressions\n"
        exit 1
    esac
done

使用方法


Usage: migrate [-b] [-c] [-r <*.sql.gz> <*.tar.gz>] [-t <"0 3 * * *">]

  -b,   backup mysql and media
  -c,   clean old-to-date backup
  -r,   restore mysql and media
  -t,   set cron schedule expressions
  • sh migrate -b 開始備份
  • sh migrate -c 開始清理舊文件
  • sh migrate -r *.sql.gz *.tar.gz 開始恢復,注意順序
  • sh migrate -t "0 3 * * *" 定時備份規則

備份

從我的 Django 項目來看,我要遷移的數據無非就是這兩個

  1. MySQL 數據庫的備份
  2. media 媒體文件,圖片、視頻、音樂之類的

操作

sh migrate -b

如果腳本保持默認,即將 MySQL備份(*.sql.gz)media備份(*.tar.gz) 存入 backup/****-**-**/文件夾中,請按需修改

目錄

.
└── backup/
    ├── 2019-12-11/
    │   ├── media-20191211-1235.tar.gz
    │   └── website-20191211-1235.sql.gz
    ├── 2019-12-12/
    │   ├── media-20191212-0326.tar.gz
    │   └── website-20191212-0326.sql.gz
    └── 2019-12-13/
        ├── media-20191213-1624.tar.gz
        └── website-20191213-1624.sql.gz

清理

因爲定時備份會佔用很大的硬盤空間,而硬盤空間又是有限的,所以要定時清理,當前默認只保存3天的備份

sh migrate -c

開啓定時備份

我使用的是 Linux 自帶的 crontab 定時任務。

定時備份是一個好習慣,不要等到了服務器崩了的時候再去備份,那樣可能會很麻煩。

以下操作 需要使用 root 用戶

sh migrate -t "0 3 * * *"
  • “0 3 * * *” 是備份的週期,表示每天凌晨3點備份一次,參考時間規則查詢網站:crontab guru

原理:

  1. 輸入crontab -e
  2. 添加內容:0 3 * * * cd 目錄 && sh migrate.sh -b -c
  3. 保存退出

crontab命令查詢

  1. 查看當前用戶的定時任務
crontab -l
  1. 檢查 cron 服務是不是在運行
service crond status

[root@localhost blogtest]# service crond status
Redirecting to /bin/systemctl status crond.service
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since 五 2019-12-06 15:42:39 CST; 1 weeks 2 days ago
 Main PID: 30726 (crond)
    Tasks: 1
   Memory: 1.2M
   CGroup: /system.slice/crond.service
           └─30726 /usr/sbin/crond -n

12月 16 10:12:01 localhost.localdomain crond[30726]: (root) RELOAD (/var/spool/cron/root)
...
  1. cron 不在運行啓動服務
service cron start
  1. 查看定時任務日誌執行信息
tail -f /var/log/cron

備份文件的導出和導入

導出

手動導出或者利用 e-mail 將備份文件定時發到自己郵箱,這個按需使用吧,基於Python的郵件模塊可以參考我的 基於Python的郵件發送模塊封裝,只要配置郵箱基本信息就可發送。

導入

  1. 放在項目根目錄,sql 無所謂,但 media 還是要的,所以乾脆都放相同目錄
  2. 項目容器運行,可用 docker-compose ps 查看

目錄:

.
├── django
├── migrate.sh
├── docker-compose.yml
├── media-20191212-0326.tar.gz
├── nginx
└── website-20191212-0326.sql.gz

恢復

在一臺新服務器上恢復項目,只需安裝 dockerdocker-compose 後,運行容器,恢復數據,即可完成遷移的全部工作

sh migrate -r *.sql.gz *.tar.gz

自動 導入sql文件解壓靜態媒體文件

好了,導入文件恢復SQL和mdeia兩步就完成了服務器的遷移,用的了五分鐘?那在導入文件的時間一定用了四分五十九秒~~

就這樣,神奇的事情發生了,一切數據全部保留~ enjoy~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章