Fragments of verbose memory

冗長な記憶の断片 - Web技術のメモをほぼ毎日更新

Jan 14, 2026 - 日記

resticprofile: 除外パターン・世代管理・スケジュールを1つのYAMLで完結させる

resticprofile のカバー画像

前回の記事「restic: node_modules と .git を除外しつつ「復元可能な開発環境」を維持する設計 」では、restic の基本的な使い方と launchd/systemd を使った自動化まで解説しました。

しかし、設定ファイルを複数管理したり、plist や unit ファイルを手書きするのは正直面倒です。macOS と Linux で異なる設定を維持するのも煩雑になりがちです。

そこで本記事では、resticprofile を使って、バックアップ設定を1つの YAML ファイルに集約する実践的な方法を紹介します。パスワード管理、除外リスト、世代管理、スケジュール——これらすべてを宣言的に管理できる快適さを体験しましょう。

resticprofile とは?

resticprofile は restic の設定を一元管理するためのラッパーツールです。Go 言語で開発されており、restic と同じクロスプラットフォーム対応が特徴です。

主な特徴

  • 設定ファイル駆動: YAML/TOML/JSON/HCL で設定を記述
  • スケジューラ抽象化: macOS(launchd)、Linux(systemd)、Windows(Task Scheduler)を統一的に扱う
  • プロファイル管理: 複数のバックアップ設定を1ファイルで管理
  • 監視連携: healthchecks.ioPrometheus 、Slack/Discord 通知に対応
  • JSON Schema サポート: VSCode などのエディタで補完・検証が可能

公式サイト: https://creativeprojects.github.io/resticprofile/

なぜ resticprofile を使うのか?

前回の記事では、以下のような設定が分散していました:

1
2
3
4
5
6
~/
├── .restic-password         # パスワードファイル
├── .restic-excludes         # 除外パターン
├── .zshrc                   # 環境変数
└── Library/LaunchAgents/    # macOS スケジュール設定
    └── dev.tumf.restic-backup.plist

これを resticprofile では1つの YAML ファイルに集約できます:

1
2
3
4
~/
└── .config/
    └── resticprofile/
        └── profiles.yaml    # すべての設定

さらに、macOS と Linux で同じ設定ファイルを共有できるため、複数マシンの管理が楽になります。

インストール

macOS

1
2
brew tap creativeprojects/tap
brew install resticprofile

Linux(バイナリ直接インストール)

1
2
3
4
5
6
7
# 最新版をダウンロード
curl -LO https://github.com/creativeprojects/resticprofile/releases/latest/download/resticprofile_linux_amd64.tar.gz

# 展開してインストール
tar xzf resticprofile_linux_amd64.tar.gz
sudo mv resticprofile /usr/local/bin/
sudo chmod +x /usr/local/bin/resticprofile

インストール確認

1
2
resticprofile version
# resticprofile version 0.31.0 commit 8a3d7f2e

Step 1: 最小構成の YAML を作成

まずは、前回の restic 設定を resticprofile に移行してみます。

ディレクトリ作成

1
mkdir -p ~/.config/resticprofile

最小構成の profiles.yaml

~/.config/resticprofile/profiles.yaml を作成:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# yaml-language-server: $schema=https://creativeprojects.github.io/resticprofile/jsonschema/config-1.json

version: "1"

# グローバル設定
global:
  default-command: snapshots
  initialize: false

# デフォルトプロファイル
default:
  repository: "/Volumes/Backup/restic-repo"
  password-file: "${HOME}/.restic-password"
  
  backup:
    source:
      - "${HOME}/work"
    exclude-caches: true
    exclude-file:
      - "${HOME}/.restic-excludes"

ポイント:

  • ${HOME} で環境変数を展開可能
  • backup: セクションに restic のオプションをそのまま記述
  • プロファイル名が default の場合、resticprofile backup で自動選択される

パスワードファイルと除外ファイルは前回と同じ

1
2
3
4
5
6
7
8
9
# パスワードファイル(前回作成済み)
cat ~/.restic-password
# your-secure-password

# 除外ファイル(前回作成済み)
cat ~/.restic-excludes
# **/node_modules
# **/.venv
# ...(前回の設定をそのまま使用)

Step 2: 動作確認

バックアップ実行

1
resticprofile backup

出力例:

2026/01/12 10:30:00 using configuration file: /Users/tumf/.config/resticprofile/profiles.yaml
2026/01/12 10:30:00 profile 'default': starting 'backup'
repository 6a3e8a9b opened (version 2, compression level auto)
created new cache in /Users/tumf/.cache/restic

Files:        8234 new,     0 changed,     0 unmodified
Dirs:          983 new,     0 changed,     0 unmodified
Added to the repository: 1.2 GiB (892 MiB stored)

processed 8234 files, 1.8 GiB in 0:45
snapshot b7e2c9a1 saved
2026/01/12 10:30:45 profile 'default': finished 'backup'

resticprofile が設定ファイルを読み込み、適切な restic コマンドを実行していることがわかります。

スナップショット確認

1
resticprofile snapshots

Dry run(実行前確認)

1
resticprofile --dry-run backup

出力例:

2026/01/12 10:32:00 using configuration file: /Users/tumf/.config/resticprofile/profiles.yaml
2026/01/12 10:32:00 profile 'default': starting 'backup'
2026/01/12 10:32:00 dry-run: /opt/homebrew/bin/restic backup \
    --password-file /Users/tumf/.restic-password \
    --repo /Volumes/Backup/restic-repo \
    --exclude-caches \
    --exclude-file /Users/tumf/.restic-excludes \
    /Users/tumf/work
2026/01/12 10:32:00 profile 'default': finished 'backup'

--dry-runコマンドの前に指定すると、resticprofile の動作確認ができます。

Step 3: 世代管理を追加

前回は restic forget コマンドを手動実行していましたが、これも YAML に書けます。

retention セクションを追加

profiles.yaml に追加:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
version: "1"

default:
  repository: "/Volumes/Backup/restic-repo"
  password-file: "${HOME}/.restic-password"
  
  backup:
    source:
      - "${HOME}/work"
    exclude-caches: true
    exclude-file:
      - "${HOME}/.restic-excludes"
  
  # 世代管理設定を追加
  retention:
    keep-last: 5
    keep-daily: 7
    keep-weekly: 4
    keep-monthly: 6
    prune: true
    after-backup: true  # バックアップ後に自動実行

ポイント:

  • after-backup: true で、バックアップ成功後に自動的に古いスナップショットを削除
  • prune: true で物理削除まで実行

動作確認

1
resticprofile backup

バックアップが完了すると、自動的に forget + prune が実行されます:

2026/01/12 10:35:00 profile 'default': starting 'backup'
[... backup ログ ...]
snapshot b7e2c9a1 saved
2026/01/12 10:35:45 profile 'default': finished 'backup'

2026/01/12 10:35:45 profile 'default': starting 'forget'
Applying Policy: keep 5 latest, 7 daily, 4 weekly, 6 monthly snapshots
keep 12 snapshots:
ID        Time                 Host        Tags        Reasons
------------------------------------------------------------------------
b7e2c9a1  2026-01-12 10:35:00  macbook                 last snapshot, daily snapshot
[...]
remove 3 snapshots:
ID        Time                 Host        Tags
------------------------------------------------------------------------
[...]

2026/01/12 10:35:48 profile 'default': starting 'prune'
counting files in repo
[...]
2026/01/12 10:36:10 profile 'default': finished 'prune'

Step 4: スケジュール設定

いよいよ本命です。launchd plist や systemd unit を書く必要はありません。

schedule セクションを追加

スケジュール文字列の書式は Schedules ドキュメント を参照してください。

profiles.yaml に追加:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: "1"

default:
  repository: "/Volumes/Backup/restic-repo"
  password-file: "${HOME}/.restic-password"
  
  backup:
    source:
      - "${HOME}/work"
    exclude-caches: true
    exclude-file:
      - "${HOME}/.restic-excludes"
    
    # スケジュール設定を追加
    schedule: "03:00"  # 毎日午前3時
    schedule-permission: "user"  # ユーザー権限で実行
  
  retention:
    keep-last: 5
    keep-daily: 7
    keep-weekly: 4
    keep-monthly: 6
    prune: true
    after-backup: true

スケジュールの登録

1
resticprofile schedule

出力例(macOS の場合):

2026/01/12 10:40:00 using configuration file: /Users/tumf/.config/resticprofile/profiles.yaml
2026/01/12 10:40:00 profile 'default': starting 'schedule'
2026/01/12 10:40:00 creating schedule backup@03:00
2026/01/12 10:40:00 analyzing crontab entry "03:00"
2026/01/12 10:40:00 schedule for backup: @daily at 03:00
2026/01/12 10:40:00 writing launchd configuration file: /Users/tumf/Library/LaunchAgents/resticprofile.backup.default.plist
2026/01/12 10:40:00 loading schedule from /Users/tumf/Library/LaunchAgents/resticprofile.backup.default.plist
2026/01/12 10:40:00 schedule loaded successfully
2026/01/12 10:40:00 profile 'default': finished 'schedule'

resticprofile が自動的に launchd plist を生成し、launchctl load まで実行してくれます。

スケジュール確認

1
resticprofile status

出力例:

Schedule: default/backup
Status: enabled
Next run: 2026-01-13 03:00:00

スケジュールの削除

1
resticprofile unschedule

Step 5: 複数プロファイルの管理

実際の運用では、複数のバックアップ設定を持つことがあります。たとえば:

  • default: 日常の開発環境バックアップ(ローカルディスク)
  • cloud: 週次のクラウドバックアップ(Backblaze B2)
  • photos: 写真アーカイブ(NAS)

これらを1つの YAML で管理できます。

複数プロファイルの設定例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
version: "1"

# デフォルトプロファイル(日次ローカル)
default:
  repository: "/Volumes/Backup/restic-repo"
  password-file: "${HOME}/.restic-password"
  
  backup:
    source:
      - "${HOME}/work"
    exclude-caches: true
    exclude-file:
      - "${HOME}/.restic-excludes"
    schedule: "03:00"
    schedule-permission: "user"
  
  retention:
    keep-last: 5
    keep-daily: 7
    keep-weekly: 4
    keep-monthly: 6
    prune: true
    after-backup: true

# クラウドプロファイル(週次)
cloud:
  repository: "b2:my-bucket:restic-repo"
  password-file: "${HOME}/.restic-password"
  
  env:
    B2_ACCOUNT_ID: "${B2_ACCOUNT_ID}"
    B2_ACCOUNT_KEY: "${B2_ACCOUNT_KEY}"
  
  backup:
    source:
      - "${HOME}/work"
    exclude-caches: true
    exclude-file:
      - "${HOME}/.restic-excludes"
    schedule: "Sun 02:00"  # 毎週日曜日 午前2時
    schedule-permission: "user"
  
  retention:
    keep-last: 3
    keep-weekly: 8
    keep-monthly: 12
    prune: true
    after-backup: true

# 写真アーカイブプロファイル(月次)
photos:
  repository: "sftp:[email protected]:/backup/photos"
  password-file: "${HOME}/.restic-password-photos"
  
  backup:
    source:
      - "${HOME}/Pictures"
    schedule: "1 04:00"  # 毎月1日 午前4時
    schedule-permission: "user"
  
  retention:
    keep-last: 2
    keep-monthly: 24
    prune: true
    after-backup: true

プロファイルの切り替え

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# デフォルトプロファイル
resticprofile backup

# 特定プロファイルを指定
resticprofile --name cloud backup
resticprofile --name photos backup

# すべてのプロファイルをスケジュール登録
resticprofile schedule
resticprofile --name cloud schedule
resticprofile --name photos schedule

Step 6: 継承(inherit)機能で DRY に

複数プロファイルで共通設定が多い場合、inherit 機能を使うと重複を減らせます。

基底プロファイルを定義

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
version: "1"

# 共通設定(基底プロファイル)
base:
  password-file: "${HOME}/.restic-password"
  
  backup:
    exclude-caches: true
    exclude-file:
      - "${HOME}/.restic-excludes"
  
  retention:
    prune: true
    after-backup: true

# デフォルトプロファイル(baseを継承)
default:
  inherit: base
  repository: "/Volumes/Backup/restic-repo"
  
  backup:
    source:
      - "${HOME}/work"
    schedule: "03:00"
    schedule-permission: "user"
  
  retention:
    keep-last: 5
    keep-daily: 7
    keep-weekly: 4
    keep-monthly: 6

# クラウドプロファイル(baseを継承)
cloud:
  inherit: base
  repository: "b2:my-bucket:restic-repo"
  
  env:
    B2_ACCOUNT_ID: "${B2_ACCOUNT_ID}"
    B2_ACCOUNT_KEY: "${B2_ACCOUNT_KEY}"
  
  backup:
    source:
      - "${HOME}/work"
    schedule: "Sun 02:00"
    schedule-permission: "user"
  
  retention:
    keep-last: 3
    keep-weekly: 8
    keep-monthly: 12

inherit: base で、base プロファイルの設定をマージします。同じキーがあれば子プロファイルの設定で上書きされます。

Step 7: 監視連携(healthchecks.io)

バックアップが失敗していることに気づかないのは致命的です。resticprofile の HTTP Hooks 機能を使って、healthchecks.io と連携しましょう。

healthchecks.io のセットアップ

  1. healthchecks.io でアカウント作成(無料プランで20チェックまで)
  2. 新しいチェックを作成(例: restic-backup
  3. Ping URL をコピー(例: https://hc-ping.com/your-uuid

send-* フックを追加

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
version: "1"

default:
  repository: "/Volumes/Backup/restic-repo"
  password-file: "${HOME}/.restic-password"
  
  backup:
    source:
      - "${HOME}/work"
    exclude-caches: true
    exclude-file:
      - "${HOME}/.restic-excludes"
    schedule: "03:00"
    schedule-permission: "user"
    
    # 監視フックを追加
    send-before:
      - method: GET
        url: "https://hc-ping.com/your-uuid/start"
    
    send-after:
      - method: GET
        url: "https://hc-ping.com/your-uuid"
    
    send-after-fail:
      method: POST
      url: "https://hc-ping.com/your-uuid/fail"
      body: "${ERROR}\n\n${ERROR_STDERR}"
      headers:
        - name: "Content-Type"
          value: "text/plain; charset=UTF-8"
  
  retention:
    keep-last: 5
    keep-daily: 7
    keep-weekly: 4
    keep-monthly: 6
    prune: true
    after-backup: true

ポイント:

  • send-before: バックアップ開始時に通知
  • send-after: 成功時に通知
  • send-after-fail: 失敗時にエラー内容を POST

動作フロー

graph TD
    START[resticprofile backup] --> LOCK[ロック取得]
    LOCK --> BEFORE[send-before: /start]
    BEFORE --> RUN[restic backup実行]
    RUN -->|成功| AFTER[send-after: /]
    RUN -->|失敗| FAIL[send-after-fail: /fail]
    AFTER --> FINALLY[send-finally]
    FAIL --> FINALLY
    FINALLY --> UNLOCK[ロック解放]
    UNLOCK --> END[終了]

これで、バックアップが失敗したら即座にメール/Slack/Discord で通知を受け取れます。

Step 8: Prometheus メトリクス出力(オプション)

Prometheus でバックアップを監視している場合、メトリクスを出力できます。

prometheus-push 設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: "1"

default:
  repository: "/Volumes/Backup/restic-repo"
  password-file: "${HOME}/.restic-password"
  
  # Prometheus Pushgateway にメトリクスを送信
  prometheus-push: "http://localhost:9091/"
  prometheus-push-job: "restic-backup"
  
  backup:
    source:
      - "${HOME}/work"
    exclude-caches: true
    exclude-file:
      - "${HOME}/.restic-excludes"
    schedule: "03:00"
    schedule-permission: "user"
    extended-status: true  # 拡張メトリクスを有効化
  
  retention:
    keep-last: 5
    keep-daily: 7
    keep-weekly: 4
    keep-monthly: 6
    prune: true
    after-backup: true

バックアップ実行後、以下のようなメトリクスが Prometheus に送信されます:

resticprofile_backup_status{profile="default"} 2  # 0=fail, 1=warning, 2=success
resticprofile_backup_duration_seconds{profile="default"} 45.3
resticprofile_backup_files_processed{profile="default"} 8234
resticprofile_backup_added_bytes{profile="default"} 1288490188

Step 9: エイリアス設定で快適に

毎回 resticprofile と打つのは長いので、エイリアスを設定します。

.zshrc / .bashrc に追加

1
2
3
4
5
6
7
# resticprofile エイリアス
alias rp='resticprofile'
alias rpb='resticprofile backup'
alias rps='resticprofile snapshots'
alias rpf='resticprofile forget'
alias rpc='resticprofile check'
alias rpst='resticprofile status'

使用例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# バックアップ実行
rpb

# スナップショット確認
rps

# スケジュール状態確認
rpst

# 検証
rpc

実践例: 私の profiles.yaml

最後に、私が実際に使っている設定を紹介します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# yaml-language-server: $schema=https://creativeprojects.github.io/resticprofile/jsonschema/config-1.json

version: "1"

global:
  default-command: snapshots
  initialize: false

# 共通設定
base:
  password-file: "${HOME}/.restic-password"

  backup:
    exclude-caches: true
    exclude-file:
      - "${HOME}/.restic-excludes"
    extended-status: true

    # 共通の監視設定
    send-before:
      - method: GET
        url: "https://hc-ping.com/${HEALTHCHECK_UUID}/start"
    send-after:
      - method: GET
        url: "https://hc-ping.com/${HEALTHCHECK_UUID}"
    send-after-fail:
      method: POST
      url: "https://hc-ping.com/${HEALTHCHECK_UUID}/fail"
      body: "${ERROR}"

  retention:
    prune: true
    after-backup: true

# デフォルトプロファイル(日次ローカル)
default:
  inherit: base
  repository: "/Volumes/Backup/restic-repo"

  env:
    HEALTHCHECK_UUID: "your-local-backup-uuid"

  backup:
    source:
      - "${HOME}/work"
      - "${HOME}/Documents"
    schedule: "03:00"
    schedule-permission: "user"

  retention:
    keep-last: 5
    keep-daily: 7
    keep-weekly: 4
    keep-monthly: 6

  # 定期検証(月次)
  check:
    schedule: "1 05:00"  # 毎月1日 午前5時
    schedule-permission: "user"
    read-data-subset: "10%"  # 10%のデータを検証

# クラウドプロファイル(週次)
cloud:
  inherit: base
  repository: "b2:my-bucket:restic-repo"

  env:
    B2_ACCOUNT_ID: "${B2_ACCOUNT_ID}"
    B2_ACCOUNT_KEY: "${B2_ACCOUNT_KEY}"
    HEALTHCHECK_UUID: "your-cloud-backup-uuid"

  backup:
    source:
      - "${HOME}/work"
      - "${HOME}/Documents"
    schedule: "Sun 02:00"
    schedule-permission: "user"

  retention:
    keep-last: 3
    keep-weekly: 8
    keep-monthly: 12

特徴

  1. base プロファイル: 共通設定を一箇所で管理
  2. 環境変数: API キーや UUID を環境変数で管理(.zshrcexport
  3. 複数バックアップ先: ローカル(日次) + クラウド(週次)
  4. 自動検証: 月1回、10%のデータを読み込んで整合性チェック
  5. 監視連携: すべてのプロファイルで healthchecks.io に通知

トラブルシューティング

スケジュールが実行されない(macOS)

1
2
3
4
5
# スケジュール状態確認
launchctl list | grep resticprofile

# ログ確認
tail -f ~/Library/Logs/resticprofile.backup.default.log

パスワードファイルが見つからない

1
2
3
4
5
# 絶対パスで指定
password-file: "/Users/tumf/.restic-password"

# または環境変数
password-file: "${HOME}/.restic-password"

環境変数が展開されない

1
2
3
4
5
# シェルで確認
echo $B2_ACCOUNT_ID

# .zshrc に export されているか確認
grep B2_ACCOUNT_ID ~/.zshrc

スケジュール実行時は、シェルの初期化ファイル(.zshrc など)が読み込まれない場合があります。~/.config/resticprofile/profiles.yaml で直接環境変数を設定するか、launchd.plistEnvironmentVariables セクションで指定してください。

また、パスワードファイルや API キーは漏洩すると致命的なので、権限も確認しておくと安全です(例: chmod 600 ~/.restic-password)。

まとめ

resticprofile を使うことで、バックアップ設定を1つの YAML ファイルに集約できました。

この記事で実現したこと:

  1. 設定の集約: パスワード、除外パターン、世代管理、スケジュールをすべて YAML で管理
  2. スケジューラ抽象化: launchd/systemd を意識せず、統一的な記法でスケジュール登録
  3. 複数プロファイル: ローカル・クラウド・NAS など、用途別の設定を1ファイルで管理
  4. 継承機能: 共通設定を基底プロファイルにまとめて DRY に
  5. 監視連携: healthchecks.io で失敗を即座に検知
  6. 自動化: after-backup: true で世代管理も自動実行

前回の restic 記事で「手動管理が面倒だな…」と感じていた部分が、すべて解消されました。特に、macOS と Linux で同じ設定ファイルを共有できるのは、複数マシンを管理する開発者にとって大きなメリットです。

次回は、resticprofile の HTTP Hooks を使った Slack/Discord 通知や、Prometheus + Grafana でのダッシュボード構築について解説する予定です。

興味のある方はぜひ試してみてください。

参考リンク