こん○○は、よふかしわーくすのよふかしさんです
よふかしさんは、さくらインターネットサーバーを契約していますが
スタンダードプランだと自動バックアップ機能がないんですよね…
以前、とある変更でやらかして元に戻すのが大変だったこともあり
これを機にUbuntuやRaspberryPiでバックアップの仕掛けを作ってみよう、という企画です
例に漏れず、ハマったところもあるので
ミニマムなコマンド、スクリプトと一緒に解説していきます…
完成した実運用しているコードは、
GitHubの yofukashi-works/Sakura_Backup_Tool リポジトリにて公開中です!
ざっくり仕様検討
さくらのスタンダードプランだと300GBまで使えるのですが
ウチの場合は、まだ数GB程度と少量しか使っていないです
1日置きにバックアップして、1週間でも数十GB程度
となれば、64GBのSDカードを突っ込んであるRaspberryPiでイケそうだなと、仕様検討しました
- RaspberryPiを24時間稼働させる(させている)
- 毎日、AM1:00からバックアップ処理を開始させる
- 差分比較し、必要に応じてスナップショットを保存するかスキップする
- 最大で7日分はスナップショットを保持する
- Python+rsyncで組む
なぜ rsync で組むのか
rsyncは、平たく言えば、同期コピーをするツールです
さくらサーバにSSHでログインし、ファイル転送して差分確認するために、rsyncを選定しました
一方で、Windowsベースだとうまく動かないので、基本的にLinuxベースで動作させます
今回は、RaspberryPi向けに組んでいますが、Ubuntuでも問題なく動作することは確認済みです
Windowsの場合はWSLを組んで動作することを確認済みです
下記記事でWSL環境構築手順を解説しています
rsyncコマンドは1行だけで、さくらサーバーのwwwディレクトリをバックアップ可能です
rsync でデータをバックアップする
ひとまず、最小構成でさくらサーバーからrsyncでバックアップする手順です
下記のコマンドで実行できます
# まずはフォルダを作成
mkdir -p /home/yofukashi/sakura-backup
# currentフォルダにさくらサーバーのデータをコピー
rsync -az --delete --checksum アカウント@ホスト:/home/アカウント/www/ /home/yofukashi/sakura-backup/current/アカウント:xxxxxxxxxx
ホスト:アカウント.sakura.ne.jp
さくらの契約情報から上記は引っ張ってきてください
パスワードを求められると思うので、それも入力してください
パスも任意で変更してください
ということで、このコマンドだけで、実際にはバックアップができてしまいます
超絶簡単ですね!
手動操作で行う場合は、これがミニマムの操作になります
自動化向けにSSH鍵を登録してログインパスワード入力を不要にする
自動化に際して、毎回パスワードを入力するのはちょっと調子悪いですよね
そこでSSH鍵を作成、サーバーに登録することで
パスワード入力を不要としつつ安全にアクセスできます
毎回パスワードを入力しなくてよい様に、SSH鍵認証を設定するコマンドは次の3行で実現可能です
# 鍵を作る(1回だけ)
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_sakura -C "sakura用"
# 公開鍵をさくらサーバに登録(さくらの管理画面 or ssh-copy-id など)
# パスワードを求められるので入力すること
ssh-copy-id -i ~/.ssh/id_ed25519_sakura.pub アカウント@アカウント.sakura.ne.jp
# 以降は -e "ssh -i 秘密鍵のパス" でパスワードなしで操作可能となる
rsync -az --delete --checksum -e "ssh -i ~/.ssh/id_ed25519_sakura" アカウント@ホスト:/home/アカウント/www/ /home/yofukashi/sakura-backup/current/鍵作成はこんな感じの画面が出ればOKです
The key's randomart image is:
+--[ED25519 256]--+
| |
| |
| |
| |
| |
| |
| |
| |
| |
+----[SHA256]-----+公開鍵登録はこんな感じの画面が出ればOKです
Number of key(s) added: 1さくらのバックアップの差分を取得してログに残す
何も考えずに毎日決まった時間にバックアップを実行し、7日分は保持しておく、
という運用であれば問題はないのですが
今回はちょっとした変更の場合、
例えばアクセスカウンターの数値のみといった場合は軽微な変更と捉え、
バックアップは実施しないことにします
WordPressのプラグインのアップデートでトラブった、といったことがあったので
そういった重要な変更時にのみ、スナップショットを残す仕様とします
先の通り、今回のバックアップはcurrentフォルダに残す仕様としたので、
次回はそれをpreviousフォルダに移行させ、最新バックアップはcurrentフォルダに取得するとします
# バックアップフォルダに移動
cd ~/sakura-backup
# currentフォルダをpreviousフォルダにコピー
cp -r current previous最新情報をcurrentフォルダに取得した後、差分を確認し、logに保存します
# バックアップフォルダに移動
cd ~/sakura-backup
# logsフォルダを作成
mkdir -p logs
# previousとcurrentの差分をrsyncを使って比較
# rsyncの結果をlogsフォルダ内にlogファイルとして出力
rsync -avnc --delete ./previous/ ./current/ | tee "logs/diff_$(date +%Y-%m-%d_%H%M%S).log"ログ取得が終わったら、previousフォルダを次回用に更新しておきます
# バックアップフォルダに移動
cd ~/sakura-backup
# previousフォルダを削除
rm -rf previous
# currentフォルダをpreviousフォルダにコピー
cp -r current previousログから重要データの変更があるかを判断する
ログが取得できたので、その内容を確認して、スナップショットを残すかどうか判断します
今回は、.txt .csv .log .tmp、という拡張子のファイルは軽微な変更として、
それ以外のファイルに変更があった場合は重要な変更と判定してみます
重要データは、例えばHTML、PHP、CSS、WordPressのテーマやプラグイン、などですね
重要データありと判断した場合、currentのデータをsnapshotフォルダにコピーすることとします
今回はロジックを伴うので、snapshot.shというファイルにする前提で記載します
#!/bin/bash
# snapshot.sh
# 最新の差分ログを確認し、重要変更が1件でもあれば current を snapshots/日時 にコピーする
# .txt .csv .log .tmp の拡張子は軽微な変更とみなし、それ以外を重要な変更とする
set -e
BASE="${BASE:-$HOME/sakura-backup}"
cd "$BASE" || { echo "ERROR: $BASE に移動できません"; exit 1; }
if [ ! -d "current" ]; then
echo "ERROR: current/ がありません、先にバックアップを取得してください"
exit 1
fi
DIFF_LOG=$(ls -t logs/diff_*.log 2>/dev/null | head -1)
if [ -z "$DIFF_LOG" ]; then
echo "ERROR: logs/diff_*.log がありません、先に差分ログを取得してください"
exit 1
fi
# rsync の行からパス部分だけ取り出す
get_path() {
sed 's/^>[-*][^[:space:]]*[[:space:]]*//; s/^deleting[[:space:]]*//' | tr -d '\r'
}
# 軽微変更の拡張子か(.txt .csv .log .tmp)
is_minor() {
echo "$1" | grep -qE '\.(txt|csv|log|tmp)(/|$)'
}
# 統計行・空行・ディレクトリ行はスキップ
is_skip() {
local s="$1"
[ -z "$s" ] && return 0
echo "$s" | grep -qE '^(sent |total size|sending incremental)' && return 0
return 1
}
has_important=false
while IFS= read -r line; do
path=$(echo "$line" | get_path)
is_skip "$path" && continue
[ -z "$path" ] && continue
if ! is_minor "$path"; then
has_important=true
break
fi
done < "$DIFF_LOG"
if [ "$has_important" = true ]; then
mkdir -p snapshots
snap="snapshots/$(date +%Y-%m-%d_%H%M%S)"
cp -a current "$snap"
echo "重要変更あり: スナップショット作成 $snap"
else
echo "重要変更なし: スナップショットは作成しない"
fi実行権限を付与してからshファイルを実行してください
# 実行権限を付与
chmod +x /home/yofukashi/sakura-backup/snapshot.shsnapshotフォルダに2026-03-15_153552、といったフォルダが作成されて
バックアップデータが入っていれば成功です

スナップショットを最大7日分だけにする
このままだと、snapshotが永遠に増え続けてしまうので、直近7日分だけを残す様にします
snapshotを保存後、7日分を超えるものは古いものから削除していきます
なので、一瞬は8日分のsnapshotが保存できるストレージ容量を確保しておく必要があります
これもロジックを伴うので、snapshot_clean.sh、という名前で保存することとします
snapshotのフォルダ名は、YYYY-MM-DD_HHMMSS、となっていることを前提とします
#!/bin/bash
# snapshot_clean.sh
# バックアップのベースディレクトリ
BASE="${BASE:-$HOME/sakura-backup}"
# 何日分のスナップショットを残すか
KEEP_DAYS=7
# ベースディレクトリへ移動
cd "$BASE"
# snapshots フォルダが無ければ終了
if [ ! -d "snapshots" ]; then
echo "[INFO] snapshots フォルダがないため、削除対象なし"
exit 0
fi
# スナップショット一覧を取得
# ls → sort で古い順に並べる
list=$(ls -1d snapshots/[0-9]*-[0-9]*-[0-9]*_* 2>/dev/null | sort)
# スナップショットの総数
count=$(echo "$list" | wc -l)
# KEEP_DAYS 以下なら削除不要
if [ "$count" -le "$KEEP_DAYS" ]; then
echo "[INFO] KEEP_DAYS=$KEEP_DAYS 以下のため、削除対象なし"
exit 0
fi
# 削除すべき件数
to_remove=$((count - KEEP_DAYS))
# 古い順に to_remove 件を削除
echo "$list" | head -n "$to_remove" | xargs rm -rf
echo "古いスナップショットを ${to_remove} 件を削除"これを実行することで、重要データ差分ありの場合の7日分のみをsnapshotとして保存できます
おわりに
今回、自身が契約しているさくらインターネットサーバー、スタンダードプランにおいて
自前でバックアップする環境構築を検討、実現することができました
最終的には記述した内容をベースとして、もう少し使いやすい様にPythonで構築
24時間稼働のRaspberryPiで定期実行させることで運用を開始しています
実運用しているPythonコードはGitHubで公開していますので
そのまま使いたい方は、下記を参照してみてください


コメント