Snap版 NextCloudのクラウドバックアップ

この記事は、[KLab Engineer Advent Calendar 2024](https://qiita.com/advent-calendar/2024/klab) の21日目の記事です。

# 近況
NextCloudを自宅サーバで構築して以来、たくさんの写真や動画をアップロードしてきました。
とある日、自宅近辺に嵐が来ました。そう、物理的な嵐です。ずっと雷が鳴り続け近所に何度も落ちるという日がありまして、停電のタイミングでついに自宅サーバにも影響が出ました。なんとサーバが物理的に故障、電源が入らなくなりました。幸いストレージは無事だったので、別のPCに環境を再構築しました。
そして去年の記事が結構間違っているところがあって(何度も繰り返したため順番が前後してしまっている・・・)こりゃまずいなと感じたもの、サーバの復旧とバックアップ対応を優先して本日を迎えてしまいました。
(そしてもうどこがまずいのか思い出せない、ごめんなさい

ということで今回はフォトサーバに使っているNextCloudのクラウドストレージへのバックアップです。

# ざっくり構成
Server1とServer2は宅内に設置、まめにバックアップを取りつつ、月一程度でクラウドにも保存。自宅が再起不能になったとしても、ファイルは生き残ってほしいわけです。
![nc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311510/efbf0a70-8120-848c-5121-7ccadbb8ced5.png)


# 今回のスクリプト
これは宅内のServer2のHDDにバックアップするスクリプト
```bash:nc_backup_local.sh
#!/bin/bash
DATA="/mnt/xxx/nextcloud/"
DST_PATH="/media/xxxxx"
DST_HOST="xx@xx"
WORK="xx"
DUMP_PATH="${WORK}/xxx"

mkdir -p ${WORK}

# いったんNexCloudを停止
echo start at $(date)
snap stop nextcloud
echo nextcloud stopped $(date)

# データストレージからバックアップストレージにコピー
rsync --rsync-path="sudo rsync" -vAax ${DATA} ${DST_HOST}:${DST_PATH}/nextcloud/
echo data backup is done $(date)

# NexCloudを起動してメンテナンスモードにする
snap start nextcloud
echo nextcloud restarted $(date)
/var/lib/snapd/snap/bin/nextcloud.occ maintenance:mode --on

# mysqlのバックアップが済んだらメンテナンスモード解除
/var/lib/snapd/snap/bin/nextcloud.mysqldump > ${DUMP_PATH}
/usr/bin/gcloud storage cp ${DUMP_PATH} ${GS_URL}

echo database backup is done $(date)
/var/lib/snapd/snap/bin/nextcloud.occ maintenance:mode --off

echo end at $(date)
```

これはGoogle Cloud Storageにバックアップするスクリプト
```bash:nc_backup_gcs.sh
#!/bin/bash
DATA="/mnt/xxx/nextcloud/"
GS_URL="gs://xxxx"
WORK="yy"
DUMP_PATH="${WORK}/yy"

mkdir -p ${WORK}

# いったんNexCloudを停止
echo start at $(date)
snap stop nextcloud
echo nextcloud stopped $(date)

# データストレージからバックアップストレージにコピー
/usr/bin/gcloud storage rsync -x '.*appdata_[a-z0-9]{12}/preview/.*' -r ${DATA} ${GS_URL}/nextcloud

echo data backup is done $(date)

# NexCloudを起動してメンテナンスモードにする
snap start nextcloud
echo nextcloud restarted $(date)
/var/lib/snapd/snap/bin/nextcloud.occ maintenance:mode --on

# mysqlのバックアップが済んだらメンテナンスモード解除
/var/lib/snapd/snap/bin/nextcloud.mysqldump > ${DUMP_PATH}
/usr/bin/gcloud storage cp ${DUMP_PATH} ${GS_URL}

echo database backup is done $(date)
/var/lib/snapd/snap/bin/nextcloud.occ maintenance:mode --off

echo end at $(date)
```

やっていることほとんど同じでファイル分ける必要もなさそうですね。
どっちにバックアップするかif文でも書いておけばよさそうです。

Google Cloud Storageに保存するにあたって気を付けたのは `プレビューを除外すること` 
`nextcloud/data` ディレクトリ配下に大量のプレビューが作られていたので、Server2にバックアップするのも結構しんどい感じがしました。元ファイルから再生成可能なものは対象から外しておきましょう
ということで `-x '.*appdata_[a-z0-9]{12}/preview/.*'` をお忘れなく

# Google Cloud Storage

## ストレージクラス
`Autoclass` にしてみました。
写真や動画は一度アップロードしたら変更がないので `Archive` になってもらえるほうが嬉しい感じです。
雑にdataディレクトリ全体をバックアップしているので更新頻度の高いファイルもありそうではあります。
うまくファイルごとにストレージクラスが移行していけば後々とてもお安くなるはず。深く考えたくない。

## リージョン
今回はリージョンを `us-west1` にしました。安いから。
基本的にダウンロードするつもりもないので安さが一番大事って感じですね。
Archive Storageになったら価格が東京の半分以下になりますね。

|ロケーション|Standard Storage（GB 単位/月）|Nearline Storage（GB 単位/月）|Coldline Storage（GB 単位/月）|Archive Storage（GB 単位/月）|
|--|--|--|--|--|
|オレゴン（us-west1）|$0.020 |$0.010|$0.004|$0.0012|
|東京（asia-northeast1）|$0.023|$0.016|$0.006|$0.0025|

# おまけ
サムネイルがあまりにも多いのである程度制限をかけることにしました。小さいものと大きいものだけにしています。
（中間もあったほうがいいのかな？
```
$ nextcloud.occ config:app:set --value="32 1024"  previewgenerator squareSizes
$ nextcloud.occ config:app:set --value="64 1024" previewgenerator widthSizes
$ nextcloud.occ config:app:set --value="64 1024" previewgenerator heightSizes
```

# おまけ2：リカバリの話
[Nextcloudサーバのデータを引越すには](https://denor.jp/nextcloud%e3%82%b5%e3%83%bc%e3%83%90%e3%81%ae%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e5%bc%95%e8%b6%8a%e3%81%99%e3%81%ab%e3%81%af)にはめちゃめちゃお世話になりました。
一言で言うならデータフォルダとデータベースさえあればあっさり復旧できました。

## 従来通りセットアップする
おおよそ[前回の記事通り](https://qiita.com/hamasan05/items/a2cfdb3530374cd616f3)にセットアップします。
※一部間違っているのは次回に直します<(_ _)>
`sudo snap connect nextcloud:removable-media` を忘れて外部ストレージが壊れかけました、要注意です

## ストレージの復旧
↑のスクリプト通りなら新しいストレージを `/mnt/xxx/nextcloud/` にマウントしてからrsyncします
historyに履歴が残っていたのでたぶんこんな感じだと思います(若干確証がありませんが)
```bash
nextcloud.occ maintenance:mode --on
rsync --rsync-path="sudo rsync" -vAax ${DST_HOST}:${DST_PATH}/nextcloud/ ${DATA}
```

## DBを復旧する
```bash
nextcloud.mysql-client -e "DROP DATABASE nextcloud"
nextcloud.mysql-client -e "CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"
nextcloud.mysql-client -D nextcloud < ${DUMP_PATH}
nextcloud.occ maintenance:mode --off
```
確かこの後念のため再起動した記憶があります。

あとはサイトトップに戻ればおおよそ元の通りになっていると思います。
※Google Cloud Storageから復旧する場合はサムネイルの再生成が必要になりますね