Django関連ファイルのバックアップ(Dropbox)

2019-07-21 / Python

概要

CentOS7でDjangoを動かすシリーズの一つです。

Djangoプロジェクトを使ってWebサイトを公開したら、バックアップについても考える必要があります。何かあったときに、アップロードしたファイルやデータベースの内容が消えてしまうのは避けなければなりません。

今回はメディアファイルやデータベースの内容をDropboxへ、Pythonプログラム上から保存していきます。各種データではなくサーバー環境全体をバックアップしたい場合は、Mondo Rescue等を使ってください。

データのバックアップですが、次の3つは最低限バックアップする必要があります。

  1. Djangoプロジェクトのソースコード

  2. メディアファイル

  3. データベースの内容

Djangoプロジェクトですが、これはGit・Githubなどを使って開発していれば問題はありません。それでバックアップされているようなものです。静的なファイルも、Djangoプロジェクトのソースコード内にあるので大丈夫ですね。

なので、アップロードされたメディアファイルと、データベースの中身をバックアップすることになります。

Dropboxの設定

保存先として、Dropboxを今回利用していきます。まず、Dropboxのアカウントは作成しておきましょう。

DropboxのDevelopperページへ行きます。「Create apps」を押しましょう。
Dropboxの設定1

ここはちょっと環境によってかわりますが、「Dropbox API」にチェックし、「Full Dropbox」を選択し、「Name your app」に適当な名前を入れます。おわったら、「Create aPP」ボタンを押します。
Dropboxの設定2

この画面に移動するので、「Generated access token」下の「Generate」ボタンを押します。表示されるトークンを今後使います
Dropboxの設定3

あとは。dropboxのapiを利用するため、pythonライブラリをインストールしておきます。

pip install dropbox

データベースのバックアップ

MariaDB(MySQL)を利用している場合の例です。

ファイル名は何でもいいのですが、サーバーにbackup_db.py のようなファイルを作り、次のようにしておきます。

import datetime
import subprocess
import dropbox

dbx = dropbox.Dropbox('さきほどGenerateしたトークン')
now = datetime.datetime.now()
db_file_name = f'{now.hour}-{now.minute}-{now.second}.db'
dropbox_path = f'/mydjango/{now.year}/{now.month}/{now.day}/{db_file_name}'

subprocess.run(f'mysqldump -u ユーザー名 データベース名 -pパスワード > {db_file_name}', shell=True)
dbx.files_upload(open(db_file_name, 'rb').read(), dropbox_path)

Dropboxへのファイルアップロードは、dbx.files_upload(ファイルデータ, Dropboxのパス)のように行います。

Dropboxのパス部分ですが、今回の例ならば結果的に /mydjango/2019/7/21/12-31-15.db といった感じの文字列になります。 アップロードされた様子

ファイルデータ部分は、subprocess.run()mysqldumpコマンドを行い、その結果できた12-31-15.dbといったデータベースのdumpファイルを指定しています。やっていることはシンプルです。

メディアファイルのバックアップ

メディアファイルを、/var/www/html/media に置いている場合の例です。

サーバーにbackup_media.pyのようなファイルを作り、次のようにしておきます。

import datetime
from pathlib import Path
import dropbox

dbx = dropbox.Dropbox('さきほどGenerateしたトークン')
now = datetime.datetime.now()
dropbox_path = f'/mydjango/{now.year}/{now.month}/{now.day}'


def upload_all_files(path):
    if path.is_dir():
        for p in path.iterdir():
            upload_all_files(p)
    elif path.is_file():
        dbx.files_upload(path.read_bytes(), dropbox_path + str(path))


# メディアファイルのアップロード
upload_all_files(Path('/var/www/html/media'))

こちらもやっていることは単純で、/var/www/html/media以下の全てのファイルを走査し、個別にdbx.files_upload()としてアップロードしているだけです。

バックアップの定期実行

あとは、上で書いたバックアップ処理を定期的に呼び出すだけです。定期的な処理はcronを使うのが一般的です。サーバーで crontab -e とコマンドを実行し、次のように入力しておきましょう。

00 0 * * * /usr/local/bin/python3.7 /home/narito/tools/backup_db.py >>/tmp/cron.log 2>>/tmp/cron_error.log
30 0 * * * /usr/local/bin/python3.7 /home/narito/tools/backup_media.py >>/tmp/cron.log 2>>/tmp/cron_error.log

毎日0時0分にDBのバックアップを、0時30分にメディアファイルのバックアップを行います。

補足ですが、今回書いたスクリプトはcron専用という訳ではありません。好きなタイミングで python backup_db.py のようにして実行することもできます。例えば、DjangoプロジェクトをFabric3を使ってデプロイではDjangoプロジェクトのデプロイを紹介していますが、デプロイ処理のはじめにでも、念のためDBのバックアップをとっておく、といったこともできるでしょう。

今回紹介した処理は、いわゆるフルバックアップです。フルバックアップでは時間や容量的に厳しくなってきたら、差分、増分バックアップを考えましょう。

この記事の関連記事

CentOS7でDjangoを動かすシリーズ

2018-10-08 / シリーズ・まとめCentOS7

- CentOS7、Nginx、Gunicornの環境でDjangoを動作させる上での、個人的なまとめ記事です。

DjangoプロジェクトをFabric3を使ってデプロイ

2018-10-15 / PythonDjangoFabric3

- CentOS7でDjangoを動かすシリーズの1つです。Fabric3を使って、Djangoアプリケーションのデプロイ作業を自動化します。

コメント欄

記事にコメントする

まだコメントはありません。