適切なバックアップツールの選択:Kopiaと代替ツールの比較
HomeLab を数年間運用してきた中で、バックアップツールをいくつか渡り歩いてきました。最初は Duplicati(データベース破損が発生するまでは Web UI が使いやすかった)、次に Restic(堅牢だが CLI のみ)、そして最終的に Kopia に落ち着きました。最適な選択は、ターミナルへの抵抗感と Web UI がワークフローに本当に必要かどうかによって変わります。
セルフホスト環境での主要な3つのツールを比較してみましょう:
- Duplicati — セットアップが最も簡単で、最初から Web UI を備えています。問題は、長時間のジョブや中断された実行後に発生する SQLite 破損バグが広く知られている点です。特に数時間動作するものや同期中にクラッシュするもので顕著です。復元がサイレントに失敗することがあり、実際にデータが必要になるまで気づかない場合があります。重要なバックアップには向きません。
- Restic — 非常に安定しており、優れた重複排除機能を持ち、システム管理者コミュニティで広く信頼されています。欠点は完全に CLI のみであること。Web インターフェース、組み込みスケジューリング、サーバーモードはありません。スクリプトによるセットアップには問題ありませんが、HomeLab サービス全体の可視性を求める場合は手間がかかります。
- Kopia — 両者の長所を組み合わせた最新の選択肢です。Restic レベルの信頼性と重複排除に加え、本格的な Web UI とサーバーモードを備えています。バックグラウンドサービスとして動作し、ブラウザや CLI からアクセスでき、複数のストレージバックエンドをサポートし、データがマシンを離れる前にクライアントサイドですべてを暗号化します。
Kubernetes 環境であれば Velero が適しています。クラスターレベルのスナップショットバックアップで、一般的なディレクトリバックアップとはまったく異なるカテゴリです。
Kopiaの強みと弱点
強み
- エンドツーエンド暗号化 — すべてのデータは宛先に届く前にクライアントサイドで AES-256-GCM によって暗号化されます。ストレージバックエンドは平文を見ることがありません。完全にコントロールできないクラウドストレージにプッシュする際に重要です。B2 アカウントが侵害されても、攻撃者は解読できない暗号化された塊を持ち去るだけです。
- コンテンツアドレス指定による重複排除 — Kopia はファイルを可変長チャンクに分割し、すべてのスナップショット全体で各ユニークなチャンクを一度だけ保存します。60% が時間的に重複している 100GB の Docker ボリュームをバックアップすると、実際に保存されるのは約 40GB です。毎日のスナップショットを数週間続けるほど効果が大きくなります。
- 1つのツールで複数のバックエンドに対応 — S3 互換(AWS、MinIO、Cloudflare R2)、Backblaze B2、ローカルファイルシステム、SFTP、WebDAV、Google Cloud Storage、Azure Blob。宛先ごとに異なるツールを用意する必要はありません。
- REST API と Web UI を備えたサーバーモード — ターミナルを触ることなく、スナップショットの閲覧、バックアップのトリガー、重複排除率の監視、ポリシーの管理ができます。ローカルネットワーク上の任意のブラウザからアクセス可能です。
- 圧縮 — 重複排除に加えてオプションの zstd 圧縮を利用できます。ログ、設定ファイル、データベースダンプに特に効果的です。
弱点
- リポジトリのロックイン — Kopia のリポジトリ形式は Kopia 独自のものです。Restic やその他のツールで Kopia のリポジトリを開くことはできません。移行する場合はすべてをゼロから再アップロードする必要があります。
- 高度なシナリオでのドキュメント不足 — 公式ドキュメントは一般的なケースには十分です。ただし、カスタムリテンションのチューニング、メンテナンスのスケジューリング、エッジケースの復元については、GitHub の issue や Discord を掘り下げる必要があります。
- 組み込みアラートなし — バックアップが失敗しても Kopia は何も通知しません。外部で対応する必要があります。終了コードを確認して Telegram やメールアラートを発火する cron ラッパーで十分です。なければ、UI を開くまで失敗したジョブに気づきません。
- 比較的新しいエコシステム — Kopia はプロダクション対応ですが、Restic より新しいツールです。予期せぬ問題が発生した場合、参考にできる Stack Overflow の回答やコミュニティの投稿が少ない状況です。
HomeLab向け推奨セットアップ
このセットアップは私の HomeLab で1年以上、リポジトリの破損ゼロで稼働しています。Docker 上の Kopia がローカル NAS と Backblaze B2 にバックアップし、オフサイトの冗長性を確保しています。信頼性を維持するためのいくつかの設計上の決断があります:
- Docker 内でサーバーモードで Kopia を実行する — Web UI はローカルポートのみに公開し、Tailscale または SSH トンネル経由でアクセスする。公開インターネットには絶対に公開しない。
- 2つのリポジトリを使用する — 1つはローカル(高速な復元、転送コストなし)、もう1つはクラウド(オフサイトの災害復旧)。異なるパスワード、同じソースデータ。
- Docker ボリュームを読み取り専用ソースとして Kopia コンテナに直接マウントする — データベースの場合は、まずダンプしてからダンプファイルをバックアップする。
- バックアップとメンテナンスのスケジュールを分ける — バックアップは数時間ごとに実行し、ガベージコレクションとコンパクションは週次で実行する。混在させると不要なオーバーヘッドが発生する。
DockerへのKopiaのデプロイ:ステップバイステップ
1. Docker Composeファイルの作成
作業ディレクトリを作成し、docker-compose.yml を追加します:
version: "3.8"
services:
kopia:
image: kopia/kopia:latest
container_name: kopia
restart: unless-stopped
ports:
- "51515:51515"
volumes:
- /opt/kopia/config:/app/config
- /opt/kopia/cache:/app/cache
- /opt/kopia/logs:/app/logs
- /mnt/nas/backups:/backups # ローカルバックアップの保存先
- /opt/appdata:/data:ro # ソースデータ(読み取り専用)
environment:
- KOPIA_PASSWORD=your-strong-repo-password
- TZ=Asia/Tokyo
command:
- server
- start
- --insecure
- --address=0.0.0.0:51515
- --server-username=admin
- --server-password=your-ui-password
/opt/appdata は Docker ボリュームとアプリケーションデータが実際にある場所に合わせて調整してください。ソースマウントの :ro フラグは意図的なものです — Kopia はそこからの読み取りのみ行います。
2. リポジトリの初期化
コンテナを起動し、バックアップリポジトリを初期化します:
# コンテナを起動する
docker compose up -d
# ローカルファイルシステムリポジトリを初期化する
docker exec -it kopia kopia repository create filesystem \
--path=/backups/kopia-repo \
--password=your-repo-password
# またはオフサイト用にBackblaze B2リポジトリを初期化する
docker exec -it kopia kopia repository create b2 \
--bucket=your-bucket-name \
--key-id=your-b2-key-id \
--key=your-b2-application-key \
--password=your-repo-password
リポジトリのパスワードはすべてのデータの暗号化キーです。サーバーから物理的に離れた場所に保管してください — パスワードマネージャーへの登録と別の部屋に印刷したコピーが最低限の対策です。紛失すると、バックアップは永久に復元不可能になります。Kopia にバックドアはありません。
3. コンテナ再構築後の再接続
コンテナが再作成されて設定状態が失われた場合、既存のリポジトリに再接続します:
docker exec -it kopia kopia repository connect filesystem \
--path=/backups/kopia-repo \
--password=your-repo-password
4. バックアップポリシーの作成
ポリシーはソースパスの保持と圧縮の設定を定義します:
# データディレクトリのポリシーを設定する
docker exec -it kopia kopia policy set /data \
--compression=zstd \
--keep-latest=10 \
--keep-hourly=24 \
--keep-daily=7 \
--keep-weekly=4 \
--keep-monthly=6
# 最初のスナップショットを手動で作成する
docker exec -it kopia kopia snapshot create /data
5. 自動バックアップのスケジュール設定
Kopia のサーバーモードは初期状態でスナップショットを自動スケジュールしません。ホスト上のシンプルな cron ジョブがこれをきれいに処理します:
# ホストのcrontabを編集する
crontab -e
# 6時間ごとにバックアップを実行する
0 */6 * * * docker exec kopia kopia snapshot create /data >> /var/log/kopia-backup.log 2>&1
# 毎週フルメンテナンス(ガベージコレクション+コンパクション)
0 3 * * 0 docker exec kopia kopia maintenance run --full >> /var/log/kopia-maintenance.log 2>&1
6. Web UIへのアクセス
ブラウザで http://your-homelab-ip:51515 を開き、compose ファイルで設定した認証情報でログインします。ダッシュボードにはスナップショットの履歴とストレージ使用量が表示されます。任意のスナップショットをドリルダウンして個別のファイルをブラウズできます — すべてをダウンロードせずに復元を確認するのに便利です。
ポート 51515 は内部専用として扱ってください。直接公開するのではなく、Tailscale、WireGuard、または SSH トンネル(ssh -L 51515:localhost:51515 user@homelab-host)経由でアクセスしてください。
7. スナップショットからの復元
# 利用可能なスナップショットを一覧表示する
docker exec -it kopia kopia snapshot list /data
# IDで特定のスナップショットを復元する
docker exec -it kopia kopia snapshot restore \
k9a8b7c6d5e4f3a2b \
/restore-target
# 完全復元なしにスナップショットをマウントしてブラウズする
docker exec -it kopia kopia mount k9a8b7c6d5e4f3a2b /mnt/kopia-mount
本番導入前に知っておくべきこと
必要になる前に復元テストを行ってください。月次の訓練をスケジュールしましょう — 一時ディレクトリに復元してファイルの整合性を確認します。一度も復元したことのないバックアップシステムは、せいぜい理論上の保護にすぎません。
初日に重複排除の統計を評価しないでください。新しいリポジトリは 0% を表示します。安定したデータセットで毎日スナップショットを1週間続けると、70〜80% が典型的な値です — 履歴を積み重ねて初めて数値に意味が生まれます。
Docker 内のデータベース(PostgreSQL、MySQL、MongoDB)については、バックアップ前に必ずファイルにダンプしてください。Kopia はデータベースの内部構造を理解していません — ライブのデータディレクトリをバックアップすると書き込み途中の不整合をキャプチャするリスクがあります。pg_dump または mysqldump を Kopia が監視するディレクトリに実行し、そのディレクトリをバックアップしてください。

