Claude × Debian サーバー編 10

第10章 データを守る

バックアップを自動にし、復元を演習する

なぜバックアップが独立した章か

ここまでの章で、あなたはサーバーを一台組み立て、サービスを動かし、外の世界に公開するところまで来た。ここで一度、立ち止まって考えてほしい。もし今、このサーバーのディスクが物理的に壊れたら、何が失われるか。

OSは失われる。だが、それは惜しくない。第3章でやった最小インストールは、手順さえ残っていれば数十分でやり直せる。第6章で作ったサービスは unit file から数分で戻せるし、第7章で入れたPostgreSQLも apt で入れ直せる。サーバー本体は、思想として最初から使い捨てだ。 第3章で最小インストールを勧めたのも、第7章でデータをデータベースに集めたのも、実はこの章への伏線だった——「作り直せるもの」と「作り直せない データ」を、最初から分けて作ってきた。

作り直せないものが一つだけある。データだ。 家族の写真、仕事のファイル、メモ、自作アプリがため込んできた記録。これらは世界に一つしかない。ディスクと一緒に消えたら、もう戻らない。

だから、この章は独立している。サーバー編で最も重要な章はここだと言ってもいい。守るべきものを決め、それを自動で取り、そして——ここが肝心だが——復元を実際に演習する

第一節 何を守るかを決める

守る対象の棚卸し

闇雲に「全部バックアップする」のは、実は下手なやり方だ。OSのシステムファイルまで丸ごと取ると、バックアップは肥大化し、復元も遅くなる。先に「何が作り直せて、何が作り直せないか」を仕分けする。

サーバーで守るべきものは、おおむね三種類に分かれる。

  1. アプリのデータ:第7章のPostgreSQLとSQLiteの中身、/srv/photos~/data のファイル群など。これが本体中の本体だ。
  2. 設定:第9章で書いた Caddyfile、第6章で作った自作の systemd unit、第7章で触ったPostgreSQLの設定、/etc 以下に手で加えた変更。
  3. この本を通じて作ってきたメモmy-server.md、各章の「Claudeに聞いてみよう」の回答集、トラブル解決ログ。

OSそのもの(/usr/bin、パッケージで入ったファイル)は、原則として守らなくていい。それらは apt で作り直せる。

設定はgitに、データはバックアップツールに——二本立て

ここで一つ、作法を分ける。

設定(テキストファイル)は、git で管理する。 これは本編第12章「設定管理の作法」でデスクトップ向けにやったことの、そのままサーバー版だ。Caddyfile も自作 unit も、すべてテキストだ。テキストは git が最も得意とする。変更の履歴が残り、「いつ・なぜこの設定にしたか」が後から辿れる。

データ(写真や文書やデータベース)は、バックアップツールで取る。 こちらはテキストではなく、量も大きく、頻繁に変わる。git には向かない。専用のバックアップツール(このあと使う restic)の仕事だ。

二本立てにする理由はこうだ。設定を git に置いておけば、復旧は「git clone して、データを書き戻す」の二段になる。設定とデータが分かれていると、何が壊れても落ち着いて対処できる。

3-2-1ルール

バックアップの世界に、古くからの目安がある。3-2-1ルールだ。データのコピーを 3 つ持つ(本番1つ+バックアップ2つ)、2 種類の異なる媒体に置く(例:内蔵SSDと外付けディスク)、そのうち 1 つは別の場所(オフサイト)に置く。一箇所が火事や水害や盗難で消えても、別の場所のコピーが生き残る、という考え方だ。個人サーバーなら厳密に守らなくてもいいが、「コピーは一つでは不安、できれば離れた場所にも一つ」という感覚だけは持っておきたい。

Claudeに聞いてみよう①:守るべきものリストを作る

私はDebianサーバーで次のものを動かしています: 〔第8章までで動かしているもの一覧。例:写真サーバー(データは /srv/photos)、ファイル共有(~/share)、自作のメモアプリ(DBはPostgreSQLの notesdb)……〕

これらについて、「データ(作り直せない・バックアップ必須)」「設定(テキスト・gitで管理)」「OS/再作成可能(守らなくてよい)」の三つに仕分けて、表にしてください。 データに分類したものについては、サーバー上の具体的なパスの候補と、バックアップで取りこぼしやすい場所(データベースは稼働中にファイルを直接コピーすると壊れる、等の注意点)も添えてください。

自分の構成を渡すと、「そのDBは稼働中のファイルコピーでは壊れる。ダンプを取るべきだ」「その設定はgit側に寄せられる」といった、自分では見落としがちな点が表に並ぶ。守るべきものリストは、この章の出発点だ。

第二節 restic で取る

なぜ restic か

バックアップツールは数多いが、このサーバー編では restic を使う。理由は四つ。

  • 一本のバイナリで動く:複雑な依存関係がない。apt 一発で入る。
  • 暗号化が標準:バックアップは最初から暗号化される。外付けディスクを盗まれても、鍵がなければ中身は読めない。
  • 重複排除する:同じデータは一度しか保存しない。毎日取っても、ディスクは思ったほど増えない。
  • 宛先が多彩:ローカルディスク、別のマシン、S3互換ストレージ、rclone経由のクラウドなど、同じ操作で様々な場所に取れる。

インストールは一行だ。

sudo apt update
                sudo apt install restic
                

ローカルUSBディスクに取ってみる

まずは一番分かりやすい、外付けUSBディスクへのバックアップで感覚を掴む。USBディスクを /mnt/backup にマウントしてある前提で進める。

最初に一度だけ、リポジトリ(バックアップの保管庫)を初期化する。

# リポジトリを初期化する(最初の一度だけ)
                restic init -r /mnt/backup/repo
                # パスワード(リポジトリ鍵)の設定を求められる。後述するが、これは絶対に失くしてはいけない
                

初期化できたら、実際にバックアップを取る。第一節で仕分けた「守るべきもの」を指定する。

# データと設定を指定してバックアップ
                restic backup -r /mnt/backup/repo /srv/photos /srv/notes ~/share /etc

                # Caddyfile や自作 unit を集めた git 作業ディレクトリも忘れずに
                restic backup -r /mnt/backup/repo ~/server-config
                

取れたかどうかは、スナップショット一覧で確認する。

# これまでに取ったバックアップ(スナップショット)の一覧
                restic snapshots -r /mnt/backup/repo
                

日付とIDの並んだ一覧が出れば成功だ。二回目以降は、変わったところだけが追加される(重複排除のおかげで速いし小さい)。

データベースは「ダンプしてから」取る

一つだけ、特別扱いが要るものがある。稼働中のデータベースだ。 第7章で入れたPostgreSQLのデータファイルを、動いたまま restic で直接コピーすると、書き込みの途中を写してしまい、戻せないバックアップができることがある。

正しい型は、「まずダンプ(テキストへの書き出し)、それをバックアップ」だ。

mkdir -p ~/backup-staging

                # PostgreSQL:データベースをSQLテキストに書き出す
                sudo -u postgres pg_dump myappdb > ~/backup-staging/myappdb.sql

                # SQLite:稼働中でも安全なコピーを作る
                sqlite3 ~/data/notes.db ".backup $HOME/backup-staging/notes-backup.db"

                # 書き出した先ごと restic で取る
                restic backup -r /mnt/backup/repo ~/backup-staging
                

pg_dump の出力はただのSQLテキストなので、中身を自分の目でもClaudeでも点検できる。戻すときは psql myappdb < myappdb.sql で流し込むだけだ。第7章の最後で予告した「データを守る入口」が、ここで本流に合流する。

リモートの宛先

3-2-1ルールを思い出してほしい。外付けディスクへのバックアップは「別の媒体」までは満たすが、「別の場所」はまだだ。restic は宛先を変えるだけで、離れた場所にも取れる。

  • 別マシン(SFTP経由)-r sftp:ユーザー@別のホスト:/path/to/repo
  • S3互換ストレージ:環境変数で鍵を渡し、-r s3:... を指定
  • rclone経由:rclone が対応する多数のクラウドへ、-r rclone:remote:path

ここで、本書の前提(データは自分で管理する)とクラウド宛先の関係をはっきりさせておく。restic は、バックアップを手元で暗号化してから送る。 だから宛先にクラウドを使っても、事業者に見えるのは意味を持たない暗号データの塊だけで、鍵はあなたの手元にある。「別の場所」を二台目の機械や実家・職場のディスクで満たせるなら、それが前提に最も素直だ。本体がVPSにあるなら、自宅の機械を「別の場所」にする逆向きのバックアップが自然だ。だが暗号化済みのバックアップに限っては、クラウドを借りても主導権は手放していない——線はここに引ける。

具体的なコマンドは、あなたが選ぶ宛先によって細部が変わる。自分の宛先に合わせたコマンドは、Claudeに書いてもらうのが速い(後述の枠②)。

鍵を失くしたバックアップは、ただの乱数

ここで最も大事な注意を一つ。restic のバックアップは暗号化されている。つまり、初期化のときに設定したパスワード(リポジトリ鍵)を失くすと、バックアップは永遠に復元できない。 暗号化された乱数の山が残るだけだ。

だから鍵は、サーバーの外に、安全に保管する。パスワードマネージャに入れる、紙に書いて金庫に置く、信頼できる別の場所に控える——方法は何でもいいが、「サーバーが丸ごと消えても手元に残る場所」に置くこと。サーバーの中だけに鍵を置いていたら、サーバーが壊れた瞬間に鍵も一緒に消える。これでは本末転倒だ。

Claudeに聞いてみよう②:バックアップ用のコマンドを自分の宛先向けに書かせる

私はDebianサーバーで restic を使ってバックアップを取りたいです。 守る対象(パス):〔第一節①で作った表のデータ部分を貼る〕 バックアップの宛先:〔例:自宅NASのSFTP / Backblaze B2 / rclone経由のGoogle Drive など、決まっている範囲で〕

この宛先向けに、(1) リポジトリの初期化コマンド (2) バックアップを取るコマンド (3) スナップショットを確認するコマンド を書いてください。 パスワード(リポジトリ鍵)と、宛先の認証情報を、どこに・どう保管するのが安全かも教えてください。各コマンドが何をしているか一行ずつ説明を添えてください。

宛先ごとの細かな違い(環境変数の名前、URLの書式)は、自分で覚える必要はない。Claudeに自分の構成を渡し、出てきたコマンドを一行ずつ理解しながら使う。これがこの本の流儀だ。

第三節 自動化する

第6章の systemd timer をそのまま使う

バックアップは「気が向いたときに手で取る」では続かない。必ず取り忘れる。だから自動化する。ここで使う道具は、第6章で学んだ systemd timer だ。新しいことは何も覚えなくていい——あのとき身につけた仕組みを、バックアップに当てはめるだけだ。

まず、バックアップを実行するサービスを書く。

# /etc/systemd/system/backup.service
                [Unit]
                Description=restic backup of server data
                Wants=network-online.target
                After=network-online.target

                [Service]
                Type=oneshot
                # 鍵と宛先は環境ファイルに分けておく(中身は次の説明を参照)
                EnvironmentFile=/etc/restic/backup.env
                # データベースは先にダンプしてから取る(第二節)
                ExecStartPre=/bin/sh -c 'runuser -u postgres -- pg_dump myappdb > /srv/backup-staging/myappdb.sql'
                ExecStart=/usr/bin/restic backup /srv/photos /srv/notes /srv/backup-staging /home/youruser/share /etc
                # 古いスナップショットを整理する(直近7日 + 4週間 + 6ヶ月分を残す)
                ExecStartPost=/usr/bin/restic forget --prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6
                

鍵と宛先は、サービス本体に直書きせず、環境ファイルに分ける。

# /etc/restic/backup.env (root だけが読める権限にすること)
                RESTIC_REPOSITORY=/mnt/backup/repo
                RESTIC_PASSWORD=(リポジトリ鍵)
                
# 環境ファイルは root 以外に読まれないよう、権限を絞る
                sudo chmod 600 /etc/restic/backup.env
                

次に、それを「毎日決まった時刻に動かす」タイマーを書く。

# /etc/systemd/system/backup.timer
                [Unit]
                Description=Run restic backup daily

                [Timer]
                # 毎日 04:00 に実行(時刻は負荷の低い時間帯を選ぶ)
                OnCalendar=daily
                # サーバーが止まっていて実行を逃したら、起動後に取り返す
                Persistent=true

                [Install]
                WantedBy=timers.target
                

タイマーを有効にして起動する。

sudo systemctl daemon-reload
                sudo systemctl enable --now backup.timer
                

動いているか確認する

タイマーが仕込めたら、ちゃんと予定されているか確認する。

# 登録されているタイマーの一覧と、次回実行予定の時刻
                systemctl list-timers

                # バックアップの実行結果(成功したか、失敗したか)を見る
                journalctl -u backup.service
                

list-timersbackup.timer が並び、次回実行時刻が表示されていれば、自動化は完成だ。

失敗に気付く仕組み

自動化には落とし穴が一つある。「自動で取れているつもり」が一番危ない。 ある日ディスクが満杯になって、あるいは外付けが外れていて、何週間もバックアップが失敗し続けていた——いざ復元しようとしたら何もなかった、という事故は実際によくある。

凝った監視を組むのは第11章に譲るとして、まずは素朴な運用から始めればいい。週に一度、自分の目で restic snapshots を見る。 一覧の一番上の日付が、ちゃんと「昨日」や「今朝」になっているか確かめる。これだけで、「気付かないうちに止まっていた」を防げる。

# 週に一度、これを自分の目で見る習慣をつける
                restic snapshots -r /mnt/backup/repo | tail
                

第四節 復元の演習

復元したことのないバックアップは、無いのと同じ

この章で一番伝えたいことを書く。復元したことのないバックアップは、無いのと同じだ。

バックアップは「取れている」だけでは半分でしかない。本当に大事なのは「いざというときに戻せる」ことだ。だが、取りっぱなしで一度も復元を試していないバックアップは、本当に戻せるかどうか誰も知らない。鍵を取り違えていた、肝心のディレクトリを指定し忘れていた、ファイルが壊れていた——こうした「いざ戻そうとしたら戻らなかった」は、復元を一度も演習していないから起きる。

だから、取れたら必ず一度、復元してみる

実際に復元してみる

復元の演習は、本番を上書きしないよう、別の場所(/tmp/restore-test など)に書き出す形でやる。これなら何も壊さずに試せる。

# 最新のスナップショットを、テスト用の場所に復元してみる
                restic restore latest -r /mnt/backup/repo --target /tmp/restore-test

                # 中身を確認する。守りたかったファイルが、ちゃんと入っているか
                ls -R /tmp/restore-test
                

/tmp/restore-test の中に、写真も文書も設定ファイルも、見覚えのある形で並んでいれば成功だ。この瞬間、あなたのバックアップは「あるかもしれないもの」から「確かに戻せるもの」に変わる。 確認が終わったらテスト用ディレクトリは消してよい。

上級演習:サーバー再構築

もう一段進んだ演習を提案しておく。もう一台(または手元のVMやVPS)に、ゼロからサーバーを再現してみるのだ。

手順はこうなる。第3章の最小インストールから始め、git に置いた設定(Caddyfile、自作 unit、セットアップメモ)を clone し、restic でデータを書き戻し、データベースは pg_dump のダンプを psql で流し込んで戻す。これで、本番とほぼ同じサーバーが新しい機械の上に立ち上がるはずだ。

この演習をやり遂げると、二つのことが手に入る。一つは「本当に最初から作り直せる」という確信。もう一つは、再構築の途中で必ず見つかる「手順に抜けていたもの」——メモし忘れていた設定、git に入れ忘れていたファイル。それを見つけて埋めておけば、本物の「いざ」のときに慌てずに済む。第11章で扱う「構成のコード化」は、ここに直結する。

Claudeに聞いてみよう③:復元演習の手順書を作る

私は restic で次の構成のバックアップを取っています: 守っているデータ:〔パス一覧〕 設定の管理:〔git リポジトリに Caddyfile / 自作 unit / セットアップメモを置いている、等〕 バックアップ宛先:〔ローカルUSB / SFTP / クラウド など〕

この構成を、新しい機械(VPSまたはVM)にゼロから再現する「サーバー再構築演習」の手順書を作ってください。 (1) OSの最小インストール後にやること (2) 設定をgitから戻す手順 (3) resticからデータを戻す手順 (4) 各サービスが正しく動いているか確認する方法 の順で、私の構成に合わせて具体的に。 演習の途中で「手順に抜けがあった」と気づくためのチェックリストも添えてください。

この手順書は、演習のためだけのものではない。本物の災害が起きたとき、これがそのまま復旧マニュアルになる。一度作って git に置いておけば、未来のあなた(知識が抜けた一年後のあなた)を救う。

まとめ

この章でやったこと:

  1. 「サーバー本体は使い捨て、データだけが本体」という思想を確認し、守るべきものを棚卸しした
  2. 設定は git に、データは restic に、という二本立ての方針を決めた
  3. restic でローカルディスクへ実際にバックアップを取り、スナップショットを確認した
  4. systemd timer でバックアップを毎日自動化し、list-timersjournalctl で動作を確かめた
  5. 復元を実際に演習し、バックアップが「確かに戻せるもの」であることを確認した
  6. サーバー再構築という上級演習で、「最初から作り直せる」確信を手に入れた

手元に残ったもの:

  • 暗号化されたバックアップリポジトリと、安全な場所に保管したリポジトリ鍵
  • backup.servicebackup.timer(毎日自動でバックアップを取る仕組み)
  • 「守るべきものリスト」と「復元演習の手順書」(これらは git に置く)
  • 「いざとなれば作り直せる」という、運用の余裕を生む安心感

これで、サーバーが物理的に壊れても、あなたは慌てない。OSもサービスも作り直せて、データは戻せる。最後の第11章では、この安心感を土台に、サーバーを長く育てていく話をする。週に15分の見守りで回す設計、保守のリズム、壊れたときの型、そして「次の一手」——一台のサーバーを、生き物のように手入れして育てる作法だ。


シリーズ全体はClaudeと一緒に学ぶDebian サーバー編 一覧から辿れる。本編(デスクトップ編)は全章一覧へ。コメント・議論は Facebook グループへ:AISeed — 生物多様性・食料・AIと暮らし

← 前: 第9章 外の世界に公開する 次: 第11章 サーバーを育てる →

守るのは機械ではなく、データだ。

サーバーは何度でも作り直せる。作り直せないのはデータだけだ。バックアップを自動で取り、そして実際に復元してみる——「いざ」を一度演習しておけば、サーバーが壊れた日も慌てない。その備えを、Claudeと一緒に整える。

AISeed — 生物多様性・食料・AIと暮らし(Facebook)