2026年5月24日

2026年5月24日

Duplicityでリモートバックアップをする方法:暗号化・増分・世代削除・復元まで

Duplicity は、バックアップを GnuPG(GPG)で暗号化し、初回のフルバックアップ以降は変更分だけを増分として別サーバーやクラウドへ送れるツールです。保存先のサーバーには暗号化されたファイルしか置かれないため、保存先の管理者や、万が一保存先が漏えいした場合でも中身を読まれにくいのが特長です。この記事では、SFTP で別サーバーへ送る構成を例に、初回バックアップ、増分と定期フル、世代の削除、検証と復元、自動化までの流れを説明します。

Duplicityの仕組みを先に押さえる

Duplicity は、対象のディレクトリを tar 形式の「ボリューム」に分け、差分を計算して圧縮・暗号化してから保存先に書き込みます。保存先には、データ本体のボリュームに加えて、どのファイルがどの状態だったかを記録したメタデータ(署名ファイルやマニフェスト)が置かれます。

ここで理解しておきたいのが「チェーン」の考え方です。

  • フルバックアップ:その時点のすべてのファイル
  • 増分バックアップ:直前のバックアップからの変更分だけ

ある時点に戻すには、フルバックアップと、そこから続く増分をすべて順に適用する必要があります。増分が何十個も続くと、復元に時間がかかり、途中の1つが壊れただけでそれ以降に戻れなくなります。そのため、月に1回などの頻度でフルバックアップを取り直し、チェーンを短く保つのが基本の運用です。

インストールと保存先の準備

Debian や Ubuntu では apt install duplicity で入ります。ただし、ディストリビューションのパッケージは最新版より古いことが多く、バージョンによってオプション名や対応している保存先(バックエンド)が異なります。本家のドキュメントは3.x系を対象にしています(2026年10月現在)。この記事のコマンドを試す前に、duplicity --version と man duplicity で手元のバージョンを確認してください。

保存先のサーバーでは、バックアップ専用のユーザーを作り、送信元のサーバーから SSH の鍵認証でログインできるようにしておきます。

# 送信元サーバーで(root で実行する前提の例)
ssh-keygen -t ed25519 -f /root/.ssh/backup_ed25519 -N ''
ssh-copy-id -i /root/.ssh/backup_ed25519.pub backup@backup.example.net

# 一度手動で接続し、ホスト鍵を known_hosts に登録しておく
ssh -i /root/.ssh/backup_ed25519 backup@backup.example.net exit

最初の接続を手動で済ませておくのは、cron から無人で動かしたときにホスト鍵の確認で止まらないようにするためです。保存先のユーザーには、バックアップ用ディレクトリへの書き込み以外の権限を与えないようにしておくと、送信元が侵害されたときの被害を抑えられます。

暗号化の方式を決める

Duplicity の暗号化には2つの方法があります。

  • 共通鍵(パスフレーズ):環境変数 PASSPHRASE に設定した文字列で暗号化する。手軽だが、送信元サーバーにパスフレーズを置くことになる
  • 公開鍵:--encrypt-key に GPG 鍵の ID を指定する。暗号化は公開鍵だけでできるため、復元に必要な秘密鍵を送信元サーバーに置かない運用も可能

どちらの方法でも、パスフレーズや秘密鍵を失うとバックアップは二度と復元できません。サーバーとは別の場所(パスワード管理ツールや、オフラインで保管した紙・USBメモリなど)に控えを残しておいてください。サーバーが丸ごと失われたときにこそバックアップが必要になる、という点を忘れないようにします。

この記事では手順を分かりやすくするため、共通鍵の方式で説明します。パスフレーズは root だけが読めるファイルに置きます。

# /root/.duplicity-env(chmod 600 にしておく)
export PASSPHRASE='your-long-random-passphrase'

初回のフルバックアップ

保存先の URL は、SFTP の場合 sftp://ユーザー@ホスト/パス の形です。ホスト名の後のスラッシュが1つならホームディレクトリからの相対パス、2つ(//srv/...)ならルートから始まるパスとして扱われます。ここを間違えると、意図しない場所に保存されるので注意してください。

. /root/.duplicity-env

duplicity full \
  --ssh-options="-oIdentityFile=/root/.ssh/backup_ed25519" \
  --exclude /var/www/example.com/wp-content/cache \
  /var/www/example.com \
  sftp://backup@backup.example.net//srv/backup/example.com

--exclude には、キャッシュなど再生成できるものを指定します。除外の指定はコマンドラインに書いた順に評価され、最初に一致したものが採用されます。除外が多くなる場合は --exclude-filelist でファイルにまとめると管理しやすくなります。

WordPress の場合、データベースはファイルのコピーでは整合性のある状態になりません。mysqldump や wp db export で先にダンプファイルを作り、それをバックアップ対象のディレクトリに含めてください。ダンプファイルを Web から見える場所に置かないことにも注意が必要です。

増分バックアップと定期的なフル

2回目以降は、アクションを省略するか incremental を指定すると増分バックアップになります。実際の運用では、--full-if-older-than を付けて「最後のフルから一定期間が過ぎていたら自動でフルを取る」ようにするのが便利です。

duplicity \
  --full-if-older-than 1M \
  --ssh-options="-oIdentityFile=/root/.ssh/backup_ed25519" \
  --exclude /var/www/example.com/wp-content/cache \
  /var/www/example.com \
  sftp://backup@backup.example.net//srv/backup/example.com

1M は1か月を表します。時間の指定には 7D(7日)や 2W(2週間)なども使えます。

現在の状態は collection-status で確認できます。フルと増分がいくつ、いつ作られたかが一覧で表示されるので、チェーンが長くなりすぎていないかを定期的に見ておきます。

duplicity collection-status sftp://backup@backup.example.net//srv/backup/example.com

古い世代を削除する

保存先の容量は無限ではないので、古いチェーンを削除する処理も自動化します。

# フルバックアップを新しい順に3チェーン分だけ残す
duplicity remove-all-but-n-full 3 --force \
  sftp://backup@backup.example.net//srv/backup/example.com

# 途中で失敗して残った不要なファイルを片付ける
duplicity cleanup --force \
  sftp://backup@backup.example.net//srv/backup/example.com

削除系のコマンドは --force を付けないと「消える予定のファイルを表示するだけ」で終わります。最初は --force を外して実行し、何が消えるかを確かめてから付けると安全です。期間で指定したい場合は remove-older-than 3M も使えますが、新しい増分が依存しているフルは削除されないため、チェーン単位で考えると挙動を理解しやすくなります。

検証と復元

バックアップが読める状態かは verify で確かめます。保存先のデータと、現在のローカルのファイルを比較します。--compare-data を付けると、メタデータだけでなく中身まで比較します。

duplicity verify --compare-data \
  sftp://backup@backup.example.net//srv/backup/example.com \
  /var/www/example.com

復元は、保存先の URL と展開先のディレクトリを指定します。展開先がすでにあると上書きを拒否されるので、空のディレクトリを指定します。

# 最新の状態をまるごと復元
duplicity restore \
  sftp://backup@backup.example.net//srv/backup/example.com \
  /tmp/restore-test

# 3日前の時点の wp-config.php だけを復元
duplicity restore --time 3D --path-to-restore wp-config.php \
  sftp://backup@backup.example.net//srv/backup/example.com \
  /tmp/wp-config.php.restored

単一ファイルの指定は、3.x系の man では --path-to-restore ですが、古いバージョンでは --file-to-restore という名前でした。動かない場合は手元の man で確認してください。どのファイルが含まれているかは list-current-files で一覧できます。

復元の練習は、本番のディレクトリではなく一時ディレクトリやステージング環境で行います。少なくとも一度は「別のサーバーで、控えておいたパスフレーズだけを使って復元できる」ことを確かめておくと、本当の障害のときに慌てずに済みます。

cronで自動化する

ここまでのコマンドをスクリプトにまとめ、cron から実行します。

#!/usr/bin/env bash
# /usr/local/bin/duplicity-backup.sh
set -euo pipefail
. /root/.duplicity-env

TARGET="sftp://backup@backup.example.net//srv/backup/example.com"
SSH_OPT="--ssh-options=-oIdentityFile=/root/.ssh/backup_ed25519"

duplicity --full-if-older-than 1M "$SSH_OPT" \
  --exclude /var/www/example.com/wp-content/cache \
  /var/www/example.com "$TARGET"

duplicity remove-all-but-n-full 3 --force "$SSH_OPT" "$TARGET"

unset PASSPHRASE
30 3 * * * /usr/local/bin/duplicity-backup.sh >> /var/log/duplicity-backup.log 2>&1

Duplicity は、ローカルにもメタデータのキャッシュ(既定では ~/.cache/duplicity/ 配下)を持ちます。消えても保存先から取り直せますが、そのぶん次回の実行に時間がかかります。失敗に気づけるよう、ログを確認する仕組みや失敗時の通知も用意してください。

設定ファイルで運用を簡単にしたい場合は、Duplicity のフロントエンドである duply を使う方法もあります。また、同じく暗号化と重複排除に対応したツールとして restic や BorgBackup もあり、要件によってはそちらが合うこともあります。

まとめ

  • Duplicity は GPG で暗号化した増分バックアップを、SFTP やクラウドなどのリモートへ送れるツール
  • 復元にはフルとそれ以降の増分がすべて必要なので、--full-if-older-than で定期的にフルを取り、チェーンを短く保つ
  • パスフレーズや秘密鍵を失うと復元できない。サーバー以外の場所に控えを残す
  • 削除系のコマンドは --force なしで対象を確認してから実行する
  • verify と、別環境での復元テストで「戻せること」を確かめる。オプション名はバージョンで変わることがあるので man で確認する

お気軽にご相談ください

お見積りへ お問い合わせへ
▲