サイトの中で、サーバー上にあるものが正になってるコンテンツが怖いので、バックアップをDropboxに上げる仕組みを作りました。

[ Ubuntu18 | Dropbox API v2 ]

[2022-02-20] シェルスクリプト1つで全部やるように修正。

やることは以下の通りです。

  • バックアップ対象のファイルを、現在日時をファイル名にしたzipに固める。
  • そのzipファイルをDropboxの所定のフォルダにアップロードする。
  • cronで毎日実行する。

Dropboxの準備

Dropbox APIを使うためには、あらかじめDropboxアプリを用意しておく必要があります。

今回はこれ専用にアプリ登録してきました。好きなところにファイルをアップロードしたいので、Permission typeは『Full Dropbox』を選択します。

アプリ管理画面の『Generated access token』からアクセストークンを発行すれば準備完了です。

シェルスクリプトを作る

Dropboxの準備ができたら、cronから呼び出すシェルスクリプトを書きます。

バックアップ対象ファイルをzipで固めて curl コマンドでアップロードします。

アップロードにはDropbox APIの /files/upload エンドポイントを使います。このエンドポイントは Content-upload フォーマットなので、リクエストヘッダの Dropbox-API-Arg にパラメータを、リクエストボディにファイル本文をセットします。詳しいことは公式のリファレンスを見てください。

backup.sh
#!/bin/bash
cd `dirname $0`

# Dropboxのトークンとアップロード先フォルダ
token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
remotedir=/path/to/backup

# 現在日時をYYYYMMDDhhmmss形式で取得
today=$(date "+%Y%m%d%H%M%S")

# 一時ディレクトリとzipファイル名
tmp=/tmp/backup
zipname=${today}.zip

# 一時ディレクトリ作成
mkdir -p ${tmp}/${today}

# バックアップ対象のファイルをコピー
cd ${tmp}/${today}
cp /path/to/file1 ./file1
cp -r /path/to/dir1 ./dir1

# zipで固める (※固める前のディレクトリは消える)
cd ../
zip -rm ${zipname} ${today}

# Dropboxにアップロード
curl -X POST \
  -H "Authorization: Bearer ${token}" \
  -H "Content-type: application/octet-stream" \
  -H "Dropbox-API-Arg: {\"path\":\"${remotedir}/${zipname}\",\"mode\":\"overwrite\"}" \
  --data-binary @${zipname} \
  "https://content.dropboxapi.com/2/files/upload"

ret=${?}
if [ ${ret} -ne 0 ]; then
	exit ${ret};
fi

# 送信成功したらzipファイル削除
rm -rf ${zipname}

cronで毎日実行させる

あとは、最初に作ったシェルスクリプトをcronで毎日実行させます。ここでは毎日午前3時5分に ubuntu ユーザーで動くようにしました。エラー時は tmp にログを出すようにしました。

/etc/cron.d/my_site_backup
SHELL=/bin/bash
5 3 * * * ubuntu sh /path/to/backup.sh 2>> /tmp/my_site_backup_err.log

この記事の作りだとエラー時にゴミzipが残るのが微妙ですが、今のところ失敗したことはあんまり無いので、たぶん大丈夫だと思います。

以上です。

参考にさせていただいた記事