Dropboxには、アプリケーションの設定ファイルなどのデータサイズは大きくないけど各PCに同期したいファイルを主に保存しています。このファイル群には非常に大事なものが含まれており、万が一にも誤操作などで消えてしまうと復旧に多大な時間を費やしてしまう事が懸念されることから、Dropboxのファイルを簡易世代管理付きでバックアップすることにしました。
Dropbox APIを使ってLambdaで~とも考えましたが、やりたいことに対して無駄に時間を消費してしまいそうだったので、シンプルにshで実装しました。
条件と対応
費用
- なるべく安く
- 1バックアップ1GB程度
- 週次で全バックアップ
S3のオレゴンリージョンにストレージクラスSTANDARD_IAで保存。
費用試算: 180日 / 1週間 * 1GB * $0.0125
= $0.32
/月
料金 - Amazon S3 | AWS
バックアップ期間
- バックアップ後180日で削除
S3のLifecycleを設定。
通知
- バックアップした事をメール通知
S3のEventsでバケットへのバックアップ追加をSNS経由でメール通知。
複数端末同期
- 複数のMac PCから実行
- どのPCを起動していてもバックアップ処理が実行されるように
- なるべく無駄にバックアップしないように
日次で、各PC間で実行日時を少しずらしながらバックアップスクリプトを実行して、実行時にDropbox上のファイルに最終実行日時を追記しておく。スクリプトは最終実行日時から一週間以上経過していればバックアップするように実装。
イメージ
実行環境
- OS X EL Capitan Version 10.11.3
事前準備
依存ライブラリをインストール。
$ pip install awscli
$ brew install coreutils
AWSの設定
オレゴンにS3バケットを作成。
$ aws s3api create-bucket --bucket my-dropbox-backup-xxx --region us-west-2 --create-bucket-configuration LocationConstraint=us-west-2
保存後180日後に削除されるように、バケット全体にLifecycleを設定する。
バケットにバックアップが追加されたらSNSでメール通知するように設定する。
スクリプトの配置
各PCで実行できるようにDropboxに配置する。
$HOME/Dropbox/bin/dropbox-backup:
#!/bin/sh
# --設定
S3_PATH=s3://my-dropbox-backup-xxx
ZIP_PASSWORD=xxx
BACKUP_SECOND=604800 # 1週間に1度
DROPBOX_PATH=$HOME/Dropbox
APP_DATA_PATH=$DROPBOX_PATH/.$(basename $0)
DATA_FILE=$APP_DATA_PATH/data
# 設定--
export PATH="/usr/local/bin:/usr/local/opt/coreutils/libexec/gnubin:$PATH"
export TZ='Asia/Tokyo'
DATE_FORMAT='%Y-%m-%dT%T+09:00'
mkdir -p $APP_DATA_PATH
main() {
# 初回実行時はダミーで最終実行日時を保存
if [[ ! -f $DATA_FILE ]]; then
echo "1970-01-01T09:00:00+09:00" > $DATA_FILE
fi
# 現在日時と最終実行日時
local now=$(date +"$DATE_FORMAT")
local before=$(cat $DATA_FILE)
# 差分秒数を算出
local now_unix=$(date +%s -d "$now")
local before_unix=$(date +%s -d "$before")
local n=$(expr $now_unix - $before_unix)
# 設定した秒数以上経過していたらS3にバックアップ
if [[ $n -ge $BACKUP_SECOND ]]; then
cd $DROPBOX_PATH
zip -r --password $ZIP_PASSWORD - . 2>/dev/null \
| aws s3 cp --storage-class STANDARD_IA - $S3_PATH/$(date +"%y%m%d_%H%M%S").zip
[[ $? -eq 0 ]] && echo $now > $DATA_FILE
else
echo "前回実行日時: $before, 次回実行までの秒数: $(expr $BACKUP_SECOND - $n)"
fi
}
main
実行権限を付与。
$ chmod +x $HOME/Dropbox/bin/dropbox-backup
定期実行の設定
launchdで日次実行を設定。LaunchControlから設定すれば簡単。
$HOME/Library/LaunchAgents/local.dropbox-backup.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.dropbox-backup</string>
<key>Program</key>
<string>/Users/Nori/Dropbox/bin/dropbox-backup</string>
<key>StandardErrorPath</key>
<string>/tmp/local.dropbox-backup.stderr</string>
<key>StandardOutPath</key>
<string>/tmp/local.dropbox-backup.stdout</string>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>12</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</dict>
</plist>