resticprofile で、設定をファイルに移す
前回までで restic の基本操作は一巡しました。取って、戻して、検証して、整理する。ただ、実際に毎晩動かすことを考えると、コマンドラインがそろそろ手に負えません。
export RESTIC_REPOSITORY=/srv/backup/repo
export RESTIC_PASSWORD_FILE=/root/.config/restic/password
restic backup /srv/data --exclude='*.tmp' --exclude=/srv/data/cache --exclude-caches --tag daily
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune --path /srv/data --tag daily
第1回に書いたとおり、restic には設定ファイルがありません。この状態を放置すると、シェルスクリプトが育っていきます。今回は resticprofile を挟んで、これを設定ファイルへ移します。
インストール
公式のインストールスクリプトを使います。
curl -sfL https://raw.githubusercontent.com/creativeprojects/resticprofile/master/install.sh \
| sudo sh -s -- -b /usr/local/bin v0.33.1
末尾の v0.33.1 がバージョン指定です。省略すると最新版が入ります。この連載ではバージョンを固定しています。
resticprofile version
resticprofile version 0.33.1 commit 49102a5f476be6dcc15a9f0ac092ef23fc528075
resticprofile も Go 製の単一バイナリで、restic 本体とは別物です。resticprofile は restic を呼び出すだけで、restic を置き換えません。
最初の設定ファイル
/etc/resticprofile/profiles.yaml を作ります。
version: 2
global:
restic-binary: /usr/local/bin/restic
profiles:
default:
repository: "/srv/backup/repo"
password-file: "/root/.config/restic/password"
backup:
source:
- /srv/data
exclude:
- "*.tmp"
- "/srv/data/cache"
exclude-caches: true
tag:
- daily
verbose: true
retention:
after-backup: true
keep-daily: 7
keep-weekly: 4
keep-monthly: 6
prune: true
構造を確認しておきます。
version: 2— 設定フォーマットのバージョンです。global:— 全 profile に共通の設定です。profiles.default:—defaultという名前の profile。--nameで指定しないときに使われます。backup:/retention:— restic のbackupコマンドとforgetコマンドに渡す内容です。
retention.after-backup: true が今回のポイントの1つです。バックアップが成功した直後に forget を走らせる、という指定です。前回、手で2回叩いていた処理が1回にまとまります。
YAML 以外に TOML・JSON・HCL でも書けます。拡張子で判別されるので、profiles.toml と置けば TOML として読まれます。
設定がどう解釈されたかを見る
書いた設定がそのとおり読まれているとは限りません。show で確認します。
cd /etc/resticprofile
resticprofile show
profile default:
repository: /srv/backup/repo
password-file: /root/.config/restic/password
prometheus-push-format: text
backup:
exclude-caches: true
host: true
tag: daily
verbose: true
source: /srv/data
exclude: *.tmp
/srv/data/cache
retention:
host: true
keep-daily: 7
keep-monthly: 6
keep-weekly: 4
path: /srv/data
prune: true
tag: daily
after-backup: true
書いていない項目が増えています。retention に host: true・path: /srv/data・tag: daily が入りました。resticprofile が backup の内容から自動で埋めたものです。
これは地味に重要な安全装置です。第3回で見たとおり forget は取り消せません。もし対象を絞らずに forget --keep-daily 7 を実行すると、同じリポジトリに入っている他のホスト・他の用途のスナップショットまで削除対象になります。 resticprofile は「この profile が作ったスナップショットだけ」に範囲を限定してくれます。
ただし、自動で埋まるということは、意図と違う値が入る可能性もあるということです。次の --dry-run で必ず確認してください。
何が実行されるのかを確認する
resticprofile がやっているのは、設定から restic のコマンドラインを組み立てることです。組み立てた結果はそのまま見られます。
resticprofile --dry-run backup
2026/08/14 12:13:24 using configuration file: profiles.yaml
2026/08/14 12:13:24 profile 'default': starting 'backup'
2026/08/14 12:13:24 dry-run: /usr/local/bin/restic backup --exclude=*.tmp --exclude=/srv/data/cache --exclude-caches --host=backup-host --password-file=/root/.config/restic/password --repo=/srv/backup/repo --tag=daily --verbose /srv/data
2026/08/14 12:13:24 profile 'default': finished 'backup'
2026/08/14 12:13:24 profile 'default': cleaning up repository using retention information
2026/08/14 12:13:24 dry-run: /usr/local/bin/restic forget --host=backup-host --keep-daily=7 --keep-monthly=6 --keep-weekly=4 --password-file=/root/.config/restic/password --path=/srv/data --prune --repo=/srv/backup/repo --tag=daily
冒頭に並べたコマンドラインが、そのまま出てきました。
第1回で「resticprofile は restic を隠さない」と書いたのはこの点です。ラッパーを挟むと、たいてい中で何をしているのか分からなくなります。resticprofile はそこを開けたままにしてあるので、設定を変えたら --dry-run で差分を見るという運用ができます。restic 側のドキュメントもそのまま読めます。
実際に走らせるときは --dry-run を外すだけです。
resticprofile backup
バックアップの後に forget --prune が続けて実行されます。
対象が増えたときの書き方
対象が1つで済むことは、まずありません。ドキュメントと写真、アプリのデータとDB、というように増えていきます。設定をコピーして書き換えると、共通部分が二重管理になります。
resticprofile には inherit があります。
version: 2
global:
restic-binary: /usr/local/bin/restic
groups:
nightly:
profiles:
- docs
- photos
profiles:
# 共通の土台。これ自体は直接実行しない
base:
repository: "/srv/backup/repo"
password-file: "/root/.config/restic/password"
backup:
exclude-caches: true
verbose: true
retention:
after-backup: true
keep-daily: 7
keep-weekly: 4
keep-monthly: 6
prune: true
docs:
inherit: base
backup:
source: [/srv/data]
tag: [docs]
photos:
inherit: base
backup:
source: [/srv/data2]
tag: [photos]
base に共通部分をまとめ、docs と photos は差分だけを書きます。保持ポリシーを変えたいときに触るのは base の1か所です。
groups.nightly は、複数の profile をまとめて実行するための指定です。
resticprofile --dry-run --name nightly backup
2026/08/14 12:51:32 profile 'docs': starting 'backup'
2026/08/14 12:51:32 dry-run: /usr/local/bin/restic backup --exclude-caches --host=backup-host --password-file=... --repo=/srv/backup/repo --tag=docs --verbose /srv/data
2026/08/14 12:51:32 profile 'docs': finished 'backup'
2026/08/14 12:51:32 profile 'docs': cleaning up repository using retention information
2026/08/14 12:51:32 dry-run: /usr/local/bin/restic forget --host=backup-host --keep-daily=7 ... --path=/srv/data --prune --repo=/srv/backup/repo --tag=docs
2026/08/14 12:51:32 profile 'photos': starting 'backup'
2026/08/14 12:51:32 dry-run: /usr/local/bin/restic backup --exclude-caches --host=backup-host --password-file=... --repo=/srv/backup/repo --tag=photos --verbose /srv/data2
2026/08/14 12:51:32 profile 'photos': finished 'backup'
2026/08/14 12:51:32 profile 'photos': cleaning up repository using retention information
2026/08/14 12:51:32 dry-run: /usr/local/bin/restic forget --host=backup-host --keep-daily=7 ... --path=/srv/data2 --prune --repo=/srv/backup/repo --tag=photos
docs と photos が順に実行されました。それぞれの forget に --tag=docs / --tag=photos が付いていることに注目してください。同じリポジトリを共有していても、世代整理は互いに干渉しません。
二重起動を防ぐ
第1回で挙げた restic の制約に「1つのリポジトリに同時に書き込めない」がありました。自動実行を始めると、前回の処理が終わらないうちに次が起動する、という事態が普通に起こります。
resticprofile 側でロックを持たせます。
profiles:
default:
lock: "/tmp/resticprofile-default.lock"
force-inactive-lock: true
lock はロックファイルの場所です。force-inactive-lock: true は、ロックを持っていたプロセスがすでに存在しない場合に、そのロックを無効と判断して奪う指定です。これがないと、サーバが強制終了したあとロックファイルが残り、以降のバックアップが全て失敗し続けます。
restic 側にもリポジトリのロックがあり、こちらは global で扱いを指定できます。
global:
restic-lock-retry-after: 1m
restic-stale-lock-age: 1h
show の出力にこの2つが既定値として出ていたのは、これです。
今回の到達点
- restic の引数が
profiles.yamlに移った showで解釈結果を、--dry-runで実行内容を確認できるinheritで共通部分を1か所にまとめ、groupsでまとめて実行できるretentionが profile ごとに範囲を限定してくれるlockで二重起動を防げる
まだ全て手動実行です。ここまでは「シェルスクリプトを設定ファイルに置き換えた」だけで、cron や systemd unit は自分で書く必要が残っています。
次回
次回は schedule を1行足して、systemd timer を resticprofile に生成させます。生成された unit ファイルを開いて、何が書かれているかまで読みます。自動実行を人に見えないところへ隠さないためです。
この回で使ったツール
- resticprofile — restic を設定ファイルから駆動するラッパー(設定リファレンス)
- restic — 重複排除と暗号化を備えたバックアッププログラム