# バックアップ・復元・更新

このチュートリアルでは、アウトポスト 構成、アクセス認証情報、デバイス許可、モニタリング チェックポイント、およびキューに入れられた通知をバックアップします。元の電子メール メッセージは電子メール プロバイダーに残ります。このバックアップにより、Mailwake インスタンスが復元されます。

## 1. 保存すべきもの

回復可能なバックアップには次のものが含まれます。

- 完全な `/data` ディレクトリ: `mailwake.db` 、 `secret.key` および関連する SQLite ファイル。データベースとキーを一緒に保管してください。
- 構成を構成します: ポート、ボリューム、環境設定。
- 実行中のイメージ: データベースと同じプログラム バージョンを復元します。

以下のスクリプトは、標準の Compose インストールをターゲットとしています。設定とイメージを保存し、アウトポスト を一時的に停止し、すべてのデータをコピーしてから、アウトポスト を再起動します。その間隔の間、監視は一時停止します。再起動後、アウトポスト は保存されたチェックポイントから再開し、過去 24 時間以内に受信されたフォルダー内に残っているメッセージをキャッチアップします。

インストールでリバース プロキシ構成またはホストにマウントされたその他のファイルを使用している場合は、それらのファイルもバックアップにコピーします。別のマシンに復元する場合は、パスを調整します。

## 2. 最初のバックアップを作成します

[バックアップスクリプト](/downloads/backup.sh) をダウンロードし、 `backup.sh` として保存し、サーバーのインストール ディレクトリ (たとえば、 `~/mailwake/backup.sh` ) に配置します。

バックアップ スクリプトを表示する

```sh
#!/bin/sh
# Copyright (C) 2026 Mailwake contributors
# SPDX-License-Identifier: AGPL-3.0-only
# License: https://www.gnu.org/licenses/agpl-3.0.html
# Back up a running Compose installation; execute as a user with Docker access.
set -eu

if [ "$#" -ne 2 ]; then
  echo "Usage: backup.sh /absolute/compose-directory /absolute/backup-directory" >&2
  exit 2
fi
case "$1:$2" in
  /*:/*) ;;
  *) echo "Use absolute directory paths." >&2; exit 2 ;;
esac
cd "$1"
umask 077
lock=".mailwake-backup.lock"
if ! mkdir "$lock" 2>/dev/null; then
  echo "Could not create $PWD/$lock. Check directory permissions and active backups." >&2
  exit 1
fi
restart=0
cleanup() {
  result=$?
  trap - EXIT
  if [ "$restart" -eq 1 ]; then
    docker compose start core >&2 || result=1
  fi
  rmdir "$lock" || result=1
  exit "$result"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
container=$(docker compose ps -q core)
if [ -z "$container" ]; then
  echo "Start the Core service before running this backup." >&2
  exit 1
fi
mkdir -p "$2"
backup="$2/mailwake-$(date +%Y%m%d-%H%M%S)"
test ! -e "$backup"
staging="$backup.incomplete"
mkdir "$staging"
mkdir "$staging/data"
docker compose config > "$staging/compose.yaml"
docker inspect --format '{{.Image}}' "$container" > "$staging/image-id.txt"
docker image save --output "$staging/image.tar" "$(cat "$staging/image-id.txt")"
restart=1
docker compose stop core >&2
docker compose cp core:/data/. "$staging/data/" >&2
docker compose start core >&2
restart=0
mv "$staging" "$backup"
printf 'Backup saved: %s\n' "$backup"

```

サーバーターミナルで実行します。

```
sh "$HOME/mailwake/backup.sh" "$HOME/mailwake" "$HOME/mailwake-backups"
```

**結果を確認してください**: ターミナルは新しいディレクトリ パスを含む `Backup saved:` を出力し、`docker compose ps` は アウトポスト が再び実行されていることを示します。コピーが失敗した場合、スクリプトは アウトポスト の再起動を試行し、失敗を返します。 `.incomplete` で終わるディレクトリは未完了のバックアップです。トラブルシューティングのために保管しておいてください。

ロック ディレクトリにより、スケジュールされたバックアップと手動バックアップが重複するのを防ぎます。ホストがクラッシュするかプロセスが強制終了された場合は、まずバックアップが実行されていないことを確認してから、インストール ディレクトリから `.mailwake-backup.lock` を削除して、スクリプトを再実行します。

各バックアップのレイアウトは次のとおりです。

```
mailwake-20261008-030000/
  compose.yaml
  image-id.txt
  image.tar
  data/
    mailwake.db
    secret.key
    ...
```

画像の保存には追加のディスク容量が必要ですが、アウトポスト が停止する前に保存されます。このディレクトリはプライベート権限を使用し、暗号化された認証情報とそのキーの両方が含まれています。 `data/mailwake.db` 、 `data/secret.key` 、および `image.tar` が存在することを確認し、以下の復元手順を少なくとも 1 回実行します。

## 3. 新しいボリュームに復元する

元のインスタンスを停止し、元のボリュームを保持します。どちらのインスタンスもメールボックスとデバイスの ID を共有するため、一度に 1 つだけ実行します。

```
cd ~/mailwake
docker compose stop core
```

`backup` を実際のバックアップ パスに設定します。新しいインストール ディレクトリ、そのイメージ、および構成を準備します。

```
backup="$HOME/mailwake-backups/mailwake-20261008-030000"
mkdir -p ~/mailwake-restored
cd ~/mailwake-restored
cp "$backup/compose.yaml" ./compose.yaml
docker load --input "$backup/image.tar"
restore_volume="mailwake-restored-$(date +%Y%m%d-%H%M%S)"
cat > compose.override.yaml <<EOF
name: mailwake-restored
services:
  core:
    image: $(cat "$backup/image-id.txt")
volumes:
  core-data:
    name: $restore_volume
networks:
  default:
    name: $restore_volume-network
EOF
```

Compose は `compose.override.yaml` を自動的にロードします。新しいデータ ボリュームと正確なバックアップ イメージが選択されます。コンテナーを作成し、データをコピーし、コンテナー ユーザーの所有権を設定して、以下を開始します。

```
(
  set -eu
  docker compose create --pull never core
  docker compose run --rm --no-deps -T --user 0:0 --entrypoint sh core \
    -c 'entries=$(ls -A /data) && test -z "$entries"'
  docker compose cp "$backup/data/." core:/data/
  docker compose run --rm --no-deps -T --user 0:0 --cap-add CHOWN --entrypoint chown core \
    -R 10001:10001 /data
  docker compose up -d --pull never
  docker compose logs --tail=50 core
)
```

各コマンドが成功した場合にのみ続行してください。空のボリュームのチェックが失敗した場合は、新しい `restore_volume` を選択し、オーバーライドを書き換えてコンテナーを再作成します。設定された宛先では、古いファイルと復元されたデータが混在する可能性があります。この手順では空のボリュームを使用します。

**結果を確認してください**: 元の管理者パスワードを使用してサインインします。メールボックスとフォルダーの選択はそのまま残り、監視が再開され、デバイスの許可はバックアップから取得されます。新しいセットアップ画面が表示された場合は、復元されたインスタンスを停止し、コピー パスとボリューム マウントを確認します。復号化エラーの場合は、データベースと `secret.key` が同じバックアップからのものであることを確認してください。

## 4. 復元されたインスタンスを確認する

1. メールボックス数、選択したフォルダー、および元のインストールと比較した方法を確認します。
2. チャネル テスト通知を送信し、携帯電話に届くことを確認します。
3. 別のメールボックスから監視フォルダーに新しい電子メールを送信し、その配信記録を確認します。
4. 復元されたインスタンスを再起動し、再度サインインして、その構成と監視が継続していることを確認します。

確認したら、復元されたインスタンスをリバース プロキシに指定し、 `~/mailwake-restored` から管理します。そのディレクトリを使用するようにバックアップ ジョブを更新します。回復が確認されるまで、元のインスタンスを停止したままにし、そのボリュームとバックアップを保持します。

保留中または失敗した通知はバックアップされた状態に戻り、再度配信される可能性があります。同じ手順を使用してアップグレードをロールバックし、古いデータとイメージを一緒に復元します。

## 5. バックアップをスケジュールし、オフサイトのコピーを保存します。

Linux サーバーでは、まず手動バックアップを完了してから、`crontab -e` を使用して以下を追加します。 `/home/you` を絶対パスに置き換えます。

```
PATH=/usr/local/bin:/usr/bin:/bin
0 3 * * * /bin/sh /home/you/mailwake/backup.sh /home/you/mailwake /home/you/mailwake-backups >> /home/you/mailwake-backup.log 2>&1
```

これは、サーバーのローカル タイムゾーンで毎日 03:00 に実行されます。スケジュールされたユーザーには Docker アクセスが必要です。 NAS では、タスク スケジューラで同じシェル コマンドを使用します。翌日、ログ内の新しいディレクトリと `Backup saved:` を確認します。失敗に対処する。スケジューラはバックアップが回復可能であることを確認できません。

同じディスク上のバックアップでは、ディスクまたはマシンの障害はカバーされません。完了したディレクトリを別のマシンまたは保護されたバックアップ ストレージに、たとえば SSH 経由でコピーします。

```
scp -r "$HOME/mailwake-backups/mailwake-20261008-030000" \
  backup-user@backup-host:/srv/mailwake-backups/
```

送信元、リモート ユーザー、ホスト、宛先を置き換えます。宛先でのアクセスをバックアップ管理者に制限します。保存時の暗号化が必要な場合は、暗号化ストレージを使用するか、アップロード前にアーカイブを暗号化してください。考えられる保持ポリシーは、毎日 7 コピーと毎週 4 コピーです。古いバックアップを削除する前に、オフサイト コピーと最近の復元実行を確認してください。

## Docker Run インストールをバックアップする

Docker Run のインストールでは、 `mailwake` という名前のコンテナーとボリューム `mailwake-data` を使用します。これらのコマンドはサブシェルで実行され、コピーが失敗した場合は元のコンテナーの再起動を試みます。

```
(
  set -eu
  umask 077
  backup="$HOME/mailwake-backups/mailwake-$(date +%Y%m%d-%H%M%S)"
  mkdir -p "$backup/data"
  docker inspect --format '{{.Image}}' mailwake > "$backup/image-id.txt"
  docker image save --output "$backup/image.tar" "$(cat "$backup/image-id.txt")"
  trap 'docker start mailwake >/dev/null' EXIT
  docker stop mailwake
  docker cp mailwake:/data/. "$backup/data/"
  docker start mailwake
  trap - EXIT
  printf 'Backup saved: %s\n' "$backup"
)
```

Docker Run コマンドをデータと一緒に保存します。復元するには、元のコンテナを停止し、 `image.tar` をロードし、新しいボリュームとコンテナを作成して、開始する前にデータをコピーします。

```
(
  set -eu
  backup="$HOME/mailwake-backups/mailwake-20261008-030000"
  image=$(cat "$backup/image-id.txt")
  restore_volume="mailwake-restored-$(date +%Y%m%d-%H%M%S)"
  docker stop mailwake
  docker load --input "$backup/image.tar"
  docker volume create "$restore_volume"
  docker create --name mailwake-restored --restart unless-stopped \
    --stop-timeout 30 --read-only --security-opt no-new-privileges:true --cap-drop ALL \
    -p 127.0.0.1:8080:8080 -v "$restore_volume:/data" "$image"
  docker run --rm --user 0:0 --entrypoint sh -v "$restore_volume:/data" "$image" \
    -c 'entries=$(ls -A /data) && test -z "$entries"'
  docker cp "$backup/data/." mailwake-restored:/data/
  docker run --rm --user 0:0 --entrypoint chown -v "$restore_volume:/data" "$image" \
    -R 10001:10001 /data
  docker start mailwake-restored
)
```

各コマンドが成功した場合にのみ続行し、上記の検証チェックリストに従ってください。元のコンテナとボリュームを保持し、復元されたインスタンスの実行中は元のコンテナを停止したままにします。
