ラズパイ 読む時間 約7分

ラズパイ自身を毎晩バックアップ:スクリプトと設定を NAS に完全自動で保存し、バックアップから復元できるかも試した

ラズパイ自身のスクリプト・crontab・SSH の設定・fstab を、毎晩 2:30 に NAS へ完全自動でバックアップする手順です。1 回 2 秒・5MB ほど。秘密鍵とパスワードは入れず、1 つのファイルだけ・新しい microSD に全部、のバックアップからの復元も試しました(シリーズ第 9 回)。

ラズパイ自身を毎晩バックアップ:スクリプトと設定を NAS に完全自動で保存し、バックアップから復元できるかも試した

ここまでの回で、ラズパイはレンタルサーバーのデータベースを毎晩 NAS にバックアップするようになりました。ところが、そのバックアップを動かしているラズパイ自身のスクリプトや設定は、どこにも保存されていません。

microSD カードが壊れたら、スクリプト・crontab・SSH の設定を、全部思い出して作り直すことになります。この回では、ラズパイ自身のスクリプトと設定を、毎晩 2:30 に NAS へ完全自動でバックアップします。あわせて、バックアップから復元できるかも試します。

この回の前にできていること

この回でできるようになること

  • 毎晩 2:30 に、ラズパイのスクリプトと設定が 1 つのファイルにまとまって NAS に保存される
  • 30 日分を残し、古いものは自動で消える
  • 1 つのファイルだけ・新しい microSD に全部、のどちらでも復元できる

なぜ、ラズパイ自身もバックアップするのか

第 6 回で作ったのは「レンタルサーバーのデータのバックアップ」です。それを動かすラズパイの側には、次のようなものが入っています。

  • バックアップのスクリプト(~/backup/db_backup.sh)と、そのログ
  • 毎晩動かす予定(crontab)
  • サーバーにつなぐ SSH の設定(~/.ssh/config)
  • NAS をつなぐ設定(/etc/fstab)

どれも数 KB の小さなファイルですが、作るのに時間がかかったものばかりです。microSD カードは書き込みをくり返すと傷むので、いつか読めなくなる日が来ます。そのときに、ここだけでも復元できれば、ラズパイを買い直しても元の処理をすぐ再開できます。

ラズパイの ~/backup・~/bin・~/.ssh/config・/etc/fstab・/etc/hostname を、毎晩 2:30 に NAS の /mnt/nas/backup/raspi-self/ に保存し、新しい 30 本を残す。秘密鍵と NAS のパスワードは入れない。復元するときは 1 つのファイルだけ、または新しい microSD に全部取り出して crontab を復元する

入れるもの・入れないもの

入れるもの

  • ~/backup(スクリプト・ログ・crontab の書き出し)
  • ~/bin(自分で作ったコマンド・あれば)
  • ~/.ssh/config・authorized_keys
  • /etc/fstab・/etc/hostname

入れないもの

  • SSH の秘密鍵(~/.ssh/id_…・NAS はほかの機器からも読めるため)
  • NAS のパスワードのファイル(~/.nas-credentials)
  • OS や apt で入れたソフト(入れ直せばよい)
  • 大きなデータ(写真や動画は、もともと NAS にある)

秘密鍵とパスワードは、復元するときに作り直します。手間は少し増えますが、NAS のバックアップから鍵が漏れるおそれをなくせます。あわせて、~/backup のスクリプトに、サーバーのパスワードなどを直接書いていないかも確認しておきます(NAS はほかの機器からも読めるため)。

手順 1:スクリプトを設置する

ラズパイの ~/backup/self_backup.sh に、次のスクリプトを設置します。

nano ~/backup/self_backup.sh
#!/bin/bash
# ラズパイ自身のバックアップ:スクリプトと設定を、毎晩 NAS に保存する
set -uo pipefail
# ===== ここだけ自分の環境に変える =====
DEST="/mnt/nas/backup/raspi-self"   # 第 5 回でつないだ NAS の中の、保存するフォルダ
KEEP=30                             # 残す数(毎晩 1 本なら 30 日分)
# ======================================
LOG="$HOME/backup/backup.log"
log() { echo "$(date '+%F %T') self $*" >> "$LOG"; }
mkdir -p "$DEST" || { log "NG:$DEST に書けない(NAS がつながっているか)"; exit 1; }
# crontab の内容も、ファイルに書き出して一緒に入れる
crontab -l > "$HOME/backup/crontab.current" 2>/dev/null
file="$DEST/raspi_self_$(date +%Y%m%d_%H%M).tar.gz"
H="${HOME#/}"   # 例:home/pi(ユーザー名が違っても動くように)
cd / || exit 1
tar czf "$file.part" --ignore-failed-read --exclude='__pycache__' --exclude='*.pyc' \
  "$H/backup" "$H/bin" \
  "$H/.ssh/config" "$H/.ssh/authorized_keys" \
  etc/fstab etc/hostname 2>>"$LOG"
rc=$?
if [ "$rc" -gt 1 ]; then
  rm -f "$file.part"
  log "NG:tar が止まった($rc)"
  exit 1
fi
# 確認:圧縮が壊れていない・中にファイルが並んでいる
count=$(tar tzf "$file.part" 2>/dev/null | wc -l)
if [ "$count" -lt 3 ]; then
  mv "$file.part" "$file.broken"
  log "NG:ファイルが少ない($count)"
  exit 1
fi
mv "$file.part" "$file"
log "OK $file files=$count size=$(stat -c %s "$file")"
# 新しい $KEEP 本より古いものを消す
ls -1 "$DEST"/raspi_self_*.tar.gz 2>/dev/null | sort | head -n -"$KEEP" | while read -r f; do
  rm -f "$f" && log "消した(残す数の外):$f"
done

ここだけ自分の環境に変える

  • DEST:保存するフォルダ。第 6 回と同じ NAS の backup の下に、raspi-self というフォルダを作って入れます
  • KEEP:残す数。毎晩 1 本なので、30 なら 30 日分
  • ほかに残したいフォルダがあれば、tar の行の "$H/bin" の後ろに足します(例:"$H/notify")
  • --ignore-failed-read:書いたフォルダがない(~/bin を作っていない など)ときも、止まらずにほかのファイルを保存する。これがないと、tar が「ないファイルがある」で終わりの番号 2 を返し、毎晩 NG になります

保存して閉じたら(Ctrl+O で保存、Ctrl+X で閉じる)、自分だけが動かせるようにします。

chmod 700 ~/backup/self_backup.sh

手順 2:手動で 1 回動かす

~/backup/self_backup.sh
tail -n 1 ~/backup/backup.log

次のような OK の行が出れば成功です(数字は環境で変わります)。

2026-11-10 18:27:19 self OK /mnt/nas/backup/raspi-self/raspi_self_20261110_1827.tar.gz files=219 size=5183878

家のラズパイでは、2.1 秒で、219 ファイル・約 5MB でした。スクリプトと設定だけなので、とても小さく、すぐ完了します。

手順 3:毎晩動くようにする

crontab -e を開いて、最後に次の 1 行を足します。データベースのバックアップ(第 6 回・2:40)の少し前の、2:30 に動かします。

30 2 * * * $HOME/backup/self_backup.sh >/dev/null 2>&1

次の日の朝に、ログに OK の行が増えていれば完了です。

grep self ~/backup/backup.log | tail -n 3

バックアップから復元できるかを試した

バックアップは、復元できて初めて意味があります。家のラズパイで、NAS の最新のバックアップを /tmp に取り出して、今のファイルとくらべました。

試した結果(11/10)

  • 2:30 のバックアップから、215 ファイル(取り出したあとの大きさで 8.1MB)を取り出せた
  • スクリプト(self_backup.sh)と /etc/fstab は、今のファイルとまったく同じ
  • 違ったのは、2:30 より後に直したファイルだけ(バックアップを取った時点の形で復元される)
  • SSH の秘密鍵は入っていない(決めたとおり)

1 つのファイルだけ復元する

スクリプトをまちがえて消した・書き換えてしまった、というときは、そのファイルだけを取り出します。

ls /mnt/nas/backup/raspi-self/
tar tzf /mnt/nas/backup/raspi-self/raspi_self_20261110_0230.tar.gz | head
cd / && tar xzf /mnt/nas/backup/raspi-self/raspi_self_20261110_0230.tar.gz home/pi/backup/db_backup.sh

ファイルの名前は、tar tzf の一覧に出た形(頭の / なし)で書きます。権限と日付も、バックアップのときのまま復元されます。

新しい microSD に全部復元する

  1. 第 2・3 回のとおり、新しい microSD に OS を書き込んで、SSH でつなぐ(ユーザー名は前と同じにする)
  2. 第 5 回のとおり、NAS をつなぐ(~/.nas-credentials はここで作り直す)
  3. バックアップを全部取り出して、crontab を復元する
  4. 第 6 回のとおり、SSH の鍵を作り直して、サーバーに登録し直す

3 のコマンドです(4 の鍵の作り直しは、第 6 回の手順のとおりです)。

cd / && sudo tar xzf /mnt/nas/backup/raspi-self/raspi_self_20261110_0230.tar.gz
crontab ~/backup/crontab.current
crontab -l

/etc/fstab と /etc/hostname は管理者の権限のファイルなので、sudo を付けて取り出します。取り出したあと、sudo reboot で再起動すると、NAS も自動でつながる状態になります。

つまずきやすい所

  • 「NG:…に書けない」とログに出る:NAS がつながっていません。ls /mnt/nas で中が見えるか、第 5 回の「つまずきやすい所」を見ます。
  • files= の数がとても少ない:tar の行に書いたフォルダの名前がまちがっていないか(~/backup などが本当にあるか)を見ます。
  • .broken のファイルが残っている:確認で NG になったバックアップです。古いものを消す処理の対象の外なので、中を見て原因が分かったら手動で消します。
  • 全部復元したら、ユーザー名が違う:バックアップの中は home/pi のように前のユーザー名で入っています。新しいユーザー名が違うときは、取り出したあとに自分のホームへ移します。

分からないときは、このページを AI に渡してください

このページの URL を AI(Claude など)に渡して「この手順を手伝って」と頼めば、一緒に進めてくれます。第 4 回のように AI がラズパイにつなげる形にしてあれば、ログも AI が直接見て進められます。頼み方の例です。

  • 「(このページの URL)のスクリプトに、~/notify のフォルダも入れたい」
  • 「(このページの URL)のとおりに、db_backup.sh だけを昨日のバックアップから復元して」

まとめ

ラズパイ自身のスクリプトと設定を、毎晩 2:30 に NAS へ完全自動でバックアップするようにしました。スクリプトと設定だけなので、1 回 2 秒・5MB ほどで完了します。30 日分を残し、1 つのファイルだけでも、新しい microSD に全部でも、バックアップから復元できることを試しました。

これで、レンタルサーバーのデータも、それを守るラズパイ自身も、両方 NAS に保存される形になりました。

次に読む

基本の環境づくり(第 1〜9 回)はここまでです。このあとは、ラズパイでできることを 1 つずつ紹介する、機能ごとの記事です(まとめのページ:ラズパイでできること)。

この記事を書いた人

フリースタイル

Web の仕事 25 年以上。WordPress の保守・引っ越しと、PHP の業務の仕組みづくり。 プロフィール →

まずは、お気軽にご相談ください。

相談と見積りは無料です。急ぎのときは、フォームで「急ぎ」を選んでください。