restic をインストールして、最初のバックアップを取る
前回は「保管先に何も要求しない」「暗号化を選べない」「復元の手段が3つある」という理由で restic を選びました。今回は手を動かします。到達点は、ローカルディスクにリポジトリを1つ作り、フォルダを1つバックアップして、中身を一覧できる状態です。
検証環境について この連載のコマンドと出力は、Ubuntu 24.04 のコンテナ(systemd を稼働させたもの)で実際に実行して確認したものです。restic は
0.19.1、Docker は29.6.1です。restic はメジャーバージョンが変わるとオプションの挙動が変わることがあります。手元のバージョンが違うときはrestic <サブコマンド> --helpを先に確認してください。
パッケージマネージャの restic を使わない
Ubuntu 24.04 には restic のパッケージがあります。ただし、入るのはこれです。
apt-cache policy restic
restic:
Installed: (none)
Candidate: 0.16.4-2ubuntu0.24.04.3
一方、この記事を書いている時点の最新は 0.19.1 です。3つのマイナーバージョン差があります。restic は圧縮の追加やリポジトリ形式の更新といった、リポジトリの中身に関わる変更を重ねてきたツールです。バックアップという用途では、保管先を読み書きするソフトのバージョンが古いまま固定されるのは避けたいので、この連載では公式バイナリを使います。
cd /tmp
curl -fsSLO https://github.com/restic/restic/releases/download/v0.19.1/restic_0.19.1_linux_amd64.bz2
bunzip2 restic_0.19.1_linux_amd64.bz2
sudo install -m 0755 restic_0.19.1_linux_amd64 /usr/local/bin/restic
install -m 0755 は「コピーして権限を 755 にする」を1コマンドでやるものです。cp と chmod を分けても結果は同じです。
restic version
restic 0.19.1 compiled with go1.26.4 on linux/amd64
restic は Go で書かれた単一バイナリで、ランタイムも共有ライブラリも要りません。バイナリを1つ置けば動きます。
なお restic には restic self-update があり、自分自身を最新版に置き換えられます。手軽ですが、更新のタイミングを運用側で握れなくなるので、この連載では使いません。
リポジトリとパスワードを用意する
restic の保存先をリポジトリと呼びます。今回はローカルディスクに作ります。
先にパスワードを決めます。restic のリポジトリは暗号化されており、パスワードを失うと中身は取り出せません。前回「暗号化を選べない」ことを利点として挙げましたが、その裏返しがこれです。
sudo install -d -m 0700 /root/.config/restic
head -c 32 /dev/urandom | base64 | sudo tee /root/.config/restic/password > /dev/null
sudo chmod 600 /root/.config/restic/password
人が覚えるパスワードにしていません。restic のパスワードは自動実行されるプロセスが読むもので、人が入力する機会はほとんどないからです。それなら乱数のほうが安全です。
そのかわり、このファイルは必ずサーバの外に控えを取ってください。 サーバが失われたときに一緒に失われるなら、リポジトリごと失われるのと同じです。
控えの置き場所には条件が2つあります。
- バックアップ対象が丸ごと失われても参照できること。 VPS が消えたときに一緒に消える場所――同じ VPS 上のファイル、同じアカウントで管理しているクラウドストレージ――では意味がありません。
- アクセスを管理できること。 誰がいつ取り出せるのかを決められる媒体である必要があります。
この2つを満たすのは、たとえば施錠して保管する USB メモリや、権限を分けて運用しているパスワードマネージャです。手軽さで紙を選ぶ場合も、置き場所と持ち出しの管理は同じだけ必要になります。「サーバの外に出す」だけでは足りず、「誰が取り出せるか」まで決めて初めて控えになります。
準備ができたら初期化します。
export RESTIC_REPOSITORY=/srv/backup/repo
export RESTIC_PASSWORD_FILE=/root/.config/restic/password
restic init
created restic repository ddbd781930 at /srv/backup/repo
Please note that knowledge of your password is required to access
the repository. Losing your password means that your data is
irrecoverably lost.
RESTIC_REPOSITORY と RESTIC_PASSWORD_FILE は、それぞれ -r と --password-file に対応する環境変数です。毎回オプションで渡してもいいのですが、以降のコマンドが読みにくくなるので環境変数にしています。
RESTIC_PASSWORD という環境変数もありますが、こちらはパスワードそのものを値に入れるものです。ps や環境変数のダンプから漏れる経路が増えるので、ファイル経由にしてください。
バックアップを取る
対象はこのフォルダです。
find /srv/data -type f
/srv/data/docs/estimate.md
/srv/data/docs/minutes.md
/srv/data/photos/photo1.jpg
/srv/data/photos/photo2.jpg
テキストが2つと、2 MB と 3 MB のバイナリが2つ。合計 5 MB です。
restic backup /srv/data
no parent snapshot found, will read all files
Files: 4 new, 0 changed, 0 unmodified
Dirs: 4 new, 0 changed, 0 unmodified
Added to the repository: 5.003 MiB (5.002 MiB stored)
processed 4 files, 5.000 MiB in 0:00
snapshot 3b2b9253 saved
no parent snapshot found は「前回のスナップショットが無いので全部読む」という意味です。初回なので当然そうなります。末尾の 3b2b9253 が、このスナップショットの ID です。
同じデータをもう一度取る
そのまま、何も変えずにもう一度実行します。
restic backup /srv/data
using parent snapshot 3b2b9253
Files: 0 new, 0 changed, 4 unmodified
Dirs: 0 new, 0 changed, 4 unmodified
Added to the repository: 0 B (0 B stored)
processed 4 files, 5.000 MiB in 0:00
snapshot ac6dc393 saved
Added to the repository: 0 B です。5 MB を処理して、追加されたデータは 0 バイト。それでいて新しいスナップショット ac6dc393 は作られています。
これが restic の中心にある仕組みです。restic はファイルをチャンクという可変長のかたまりに分割し、内容のハッシュで管理します。同じ内容のチャンクは、リポジトリに1つしか置きません。スナップショットは「どのチャンクをどう並べるか」という目録なので、中身が同じなら目録だけが増えます。
次に、テキストファイルへ1行だけ足します。
echo "追記した行" >> /srv/data/docs/minutes.md
restic backup /srv/data
using parent snapshot ac6dc393
Files: 0 new, 1 changed, 3 unmodified
Dirs: 0 new, 3 changed, 1 unmodified
Added to the repository: 2.167 KiB (1.404 KiB stored)
processed 4 files, 5.000 MiB in 0:00
snapshot 578b2b2f saved
追加は 2.167 KiB。5 MB のうち、変わった分だけが増えています。
どれだけ節約できているか
数字で見ます。
restic stats
Stats in restore-size mode:
Snapshots processed: 3
Total File Count: 24
Total Size: 15.000 MiB
restore-size は「全スナップショットを別々に復元したら合計何バイトになるか」です。5 MB × 3本で 15 MB。素直な数字です。
restic stats --mode raw-data
Stats in raw-data mode:
Snapshots processed: 3
Total Blob Count: 17
Total Uncompressed Size: 5.006 MiB
Total Size: 5.003 MiB
Compression Progress: 100.00%
Compression Ratio: 1.00x
raw-data は「リポジトリが実際に持っているデータ量」です。15.000 MiB ぶんの内容が、5.003 MiB で収まっています。
圧縮率が 1.00x なのは、5 MB のうち大半が /dev/urandom から作ったランダムなデータだからです。圧縮できないものは圧縮されません。実際のドキュメントやログが対象なら、ここに圧縮の効果も乗ります。
中身を確認する
スナップショットの一覧です。
restic snapshots
ID Time Host Tags Paths Size
-------------------------------------------------------------------------
3b2b9253 2026-08-14 11:47:44 backup-host /srv/data 5.000 MiB
ac6dc393 2026-08-14 11:47:45 backup-host /srv/data 5.000 MiB
578b2b2f 2026-08-14 11:47:46 backup-host /srv/data 5.000 MiB
-------------------------------------------------------------------------
3 snapshots
特定のスナップショットに何が入っているかは ls で見られます。latest は最新を指す別名です。
restic ls latest
/srv
/srv/data
/srv/data/docs
/srv/data/docs/estimate.md
/srv/data/docs/minutes.md
/srv/data/photos
/srv/data/photos/photo1.jpg
/srv/data/photos/photo2.jpg
2つのスナップショットの差分も取れます。
restic diff ac6dc393 578b2b2f
comparing snapshot ac6dc393 to 578b2b2f:
M /srv/data/docs/minutes.md
Files: 0 new, 0 removed, 1 changed
Dirs: 0 new, 0 removed
Added: 2.167 KiB
Removed: 2.151 KiB
M は変更(modified)です。「いつ壊れたのか」を追うときに、この diff が効きます。
リポジトリの中を覗く
最後に、リポジトリが何でできているかを見ておきます。
ls -1 /srv/backup/repo
config
data
index
keys
locks
snapshots
ディレクトリとファイルの集まりです。特別なファイルシステムでもデータベースでもありません。前回「保管先に何も要求しない」と書いたのは、この構造だからです。この6つを丸ごと置ける場所であれば、それが SFTP でも WebDAV でも構いません。
中身は全て暗号化されています。data/ の下のファイルを開いても、元のファイル名も内容も読めません。読めるのは config に入っている暗号化パラメータくらいです。
次回
これで「取れる」状態になりました。ただし、ここまでで一度も復元していません。復元していないバックアップは、まだバックアップとは呼べません。 次回は restore と mount で戻し方を確認し、そのうえで増え続けるスナップショットを forget と prune で整理します。90本のスナップショットを13本に減らして、リポジトリが実際に小さくなるところまで見ます。