前回は、Docker Composeのnamed volumeを停止中に.tgzへ保存し、SHA-256と復元テストまで行いました。しかし保存先が同じサーバー内なら、内蔵ディスクの故障や誤操作で元データとバックアップを同時に失う可能性があります。
今回はUbuntu Server 26.04 LTSでresticを使い、前回作った.tgzと.sha256を暗号化して外付けSSDへ保存します。保存後はスナップショット確認、リポジトリの完全読取検査、別ディレクトリへの復元、チェックサム検証、安全な取り外しまで行います。
前提は、前回のDocker Composeのnamed volumeをバックアップ・復元する手順を完了し、~/docker/nginx-lan/backupsに.tgzと対応する.sha256があることです。
この記事では、外付けSSDのパーティション作成・フォーマット・マウント設定は行いません。
すでに/mnt/backup-driveへマウント済みで、書き込み可能な専用媒体を使います。媒体の識別に自信がない場合は、書き込みを始めず管理者へ確認してください。
この記事のゴール
- 外付けSSDが想定した媒体だと照合する
- resticの復号パスワードを権限制限し、別経路にも保管する
- 暗号化リポジトリを外付けSSDへ作成する
- Dockerバックアップ一式をスナップショットとして保存する
restic check --read-dataで全データを読み取って検査する- 別ディレクトリへ復元し、すべてのSHA-256を確認する
- 保持ルールを削除なしのdry-runで確認する
- 外付けSSDを安全にアンマウントする
「サーバー外」「オフライン」「遠隔地」は別の強さ
外付けSSDへのコピーは、元の内蔵ディスクとは別媒体になります。ただし接続したままなら、誤操作やマルウェアの影響を同時に受ける可能性があります。検証後に取り外せばオフラインになりますが、同じ家に置く限り火災・盗難・水害に対する遠隔地保管にはなりません。
3-2-1は「データを3つ、2種類の媒体、1つは別拠点」という有用な目安です。この記事で完成するのは別媒体と、取り外した場合のオフライン保管までです。遠隔地コピーは別の設計として追加します。
1. 外付けSSDを正確に識別する

最も危険なのは、別のディスクやルートファイルシステムへ誤って書き込むことです。findmnt -Tだけでは、対象が未マウントでも親の/が表示される場合があります。ここでは--mountpointで、その場所自体がマウントポイントか確認します。
MOUNT_POINT='/mnt/backup-drive'
findmnt --mountpoint / --output SOURCE,TARGET,FSTYPE,OPTIONS
findmnt --mountpoint "$MOUNT_POINT" --output SOURCE,TARGET,FSTYPE,OPTIONS
lsblk --output NAME,PATH,TYPE,TRAN,SIZE,MODEL,FSTYPE,MOUNTPOINTS
df -h -- "$MOUNT_POINT"
test -w "$MOUNT_POINT"
2つのSOURCEが同じなら、外付けSSDではなくルート側へ書こうとしている可能性があります。TRAN、容量、型番、ファイルシステム、マウント先が予定と一致し、書き込み可能な場合だけ進みます。
2. resticをインストールする
sudo apt update
sudo apt install restic
restic version
Ubuntuのパッケージから導入します。バージョンが表示されなければ先へ進みません。
3. 復号パスワードを安全に作る

resticリポジトリは暗号化されます。パスワードを失うと復号できないため、長くランダムな値を使い、サーバーとは別の信頼できるパスワード管理手段にも保存します。チャット、Issue、シェル履歴へ値を書かないでください。
(
set -eu
install -d -m 700 "$HOME/.config/restic"
PASSWORD_FILE="$HOME/.config/restic/ouchi-lab-password"
test ! -e "$PASSWORD_FILE" || {
echo "STOP: パスワードファイルは既に存在します"
exit 1
}
install -m 600 /dev/null "$PASSWORD_FILE"
nano "$PASSWORD_FILE"
test -s "$PASSWORD_FILE"
stat -c '%a %U %G %n' "$PASSWORD_FILE"
)
期待する権限は600です。復旧用コピーは紙や別のパスワードマネージャーなど、外付けSSDとは別経路へ保管します。パスワードファイル自体を同じSSDだけにコピーしても、SSD紛失時の復旧にはなりません。
4. 暗号化リポジトリを初期化する
MOUNT_POINT='/mnt/backup-drive'
export RESTIC_REPOSITORY="$MOUNT_POINT/restic/ouchi-lab"
export RESTIC_PASSWORD_FILE="$HOME/.config/restic/ouchi-lab-password"
findmnt --mountpoint "$MOUNT_POINT" --output SOURCE,TARGET,FSTYPE,OPTIONS
test -r "$RESTIC_PASSWORD_FILE"
test -w "$MOUNT_POINT"
mkdir -p "$(dirname "$RESTIC_REPOSITORY")"
if test -e "$RESTIC_REPOSITORY"; then
echo "STOP: リポジトリ候補が既に存在します"
exit 1
else
restic init
fi
created restic repositoryと表示されたことを確認します。既存パスがある場合、内容を確認せず再初期化・削除しません。
5. Dockerバックアップを保存する
対象ディレクトリとファイルを先に確認します。
SOURCE_DIR="$HOME/docker/nginx-lan/backups"
test -d "$SOURCE_DIR"
find "$SOURCE_DIR" -maxdepth 1 -type f ( -name '*.tgz' -o -name '*.sha256' ) -printf '%f %s bytes
'
(
cd "$SOURCE_DIR"
test -n "$(find . -maxdepth 1 -type f -name '*.sha256' -print -quit)"
sha256sum -c -- *.sha256
)
すべてOKならresticへ保存します。
restic backup --tag ouchi-lab-nginx "$SOURCE_DIR"
restic snapshots --tag ouchi-lab-nginx
restic ls latest
スナップショットID、ホスト名、パス、タグ、保存対象の.tgzと.sha256を確認します。暗号化されても、対象を間違えたバックアップは正しくなりません。
6. リポジトリ全体を検査する

restic check
restic check --read-data
通常のcheckは構造を検査します。--read-dataはリポジトリ内のデータをすべて読み取り、保存データの整合性まで確認するため時間がかかります。初回作成時と定期的な保守で実施し、エラーがあればSSDを取り外す前に記録します。
7. 別ディレクトリへ復元してSHA-256を確認する
元のbackupsへ上書きせず、所有ユーザーだけが使う一時ディレクトリへ復元します。
RESTORE_DIR="$(mktemp -d "$HOME/restic-restore-test.XXXXXX")"
chmod 700 "$RESTORE_DIR"
printf 'RESTORE_DIR=%s
' "$RESTORE_DIR"
restic restore latest --target "$RESTORE_DIR"
RESTORED_BACKUPS="$RESTORE_DIR$SOURCE_DIR"
test -d "$RESTORED_BACKUPS"
(
cd "$RESTORED_BACKUPS"
test -n "$(find . -maxdepth 1 -type f -name '*.sha256' -print -quit)"
sha256sum -c -- *.sha256
)
すべてOKになれば、「暗号化して保存したデータを、パスワードで開き、別の場所へ復元し、元のチェックサムまで一致する」ことを確認できました。一時ディレクトリは確認が終わるまで残し、削除する場合も表示された具体的なパスを再確認します。
8. 世代保持ルールをdry-runする
例として日次7、週次4、月次6を保持する候補を確認します。今回は削除しません。
restic forget --tag ouchi-lab-nginx --group-by host,paths,tags --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --dry-run
保持・削除候補が意図どおりか、複数回のバックアップを重ねてから判断します。この記事ではforgetの実行、--prune、自動削除を行いません。
9. 外付けSSDを安全に取り外す
バックアップ、検査、復元確認が成功し、SSDを使っているシェルやプロセスがないことを確認します。
MOUNT_POINT='/mnt/backup-drive'
cd "$HOME"
sync
sudo umount -- "$MOUNT_POINT"
if findmnt --mountpoint "$MOUNT_POINT" >/dev/null; then
echo "STOP: まだマウントされています"
else
echo "取り外し可能です"
fi
target is busyなら、強制・lazyアンマウントで回避せず、開いている端末やプロセスを確認します。アンマウント成功を確認してからケーブルを抜きます。
トラブルシューティング
wrong password or no key found
RESTIC_PASSWORD_FILEが正しいか、末尾の不要な空白がないか確認します。思いつきで上書きせず、別経路に保管した復旧用パスワードと照合します。
repository does not exist
printf '%s
' "$RESTIC_REPOSITORY"
findmnt --mountpoint /mnt/backup-drive
ls -ld /mnt/backup-drive/restic/ouchi-lab
外付けSSDが未マウントのまま、内蔵ディスク上の空ディレクトリを見ていないか確認します。
check –read-dataでエラーになる
出力を保存し、同じSSDへの新しい書き込みや削除を止めます。接続、ファイルシステム、媒体状態を確認し、正常な別バックアップから復旧できるかを優先します。
完了チェックリスト
- マウント元、接続方式、容量、型番を照合した
- resticパスワードファイルが
600で、別経路にも復旧情報がある - 外付けSSD上へ暗号化リポジトリを初期化した
- 元の
.sha256がOKのバックアップだけを保存した - スナップショットと保存ファイルを確認した
checkとcheck --read-dataが成功した- 別ディレクトリへ復元し、すべてのSHA-256が一致した
- 保持ルールを
--dry-runだけで確認した - アンマウント成功後にSSDを取り外した
まとめ
外付けSSDへファイルをコピーするだけでなく、媒体を正しく識別し、暗号化し、全データを検査し、別の場所へ復元して、取り外すところまでを一連のバックアップ運用にします。パスワードはリポジトリと別経路で守り、削除ルールは複数世代を確認してから導入します。
resticのリポジトリ作成とパスワード、整合性検査、復元、保持ルールは、リポジトリ準備、リポジトリ検査、復元、スナップショット削除方針の公式文書で確認できます。マウントポイント判定はfindmntのマニュアルを確認しました。公式情報の確認日は2026年8月3日です。
次は、マウント確認、バックアップ、検査、結果通知をsystemd timerで自動化します。失敗時にはSSDを勝手に取り外さず、人が原因を確認できる設計にします。



コメント