追記
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Rikuoh Tsujitani 2023-11-13 20:39:32 +09:00
parent 4b3333d49a
commit 625f89c4b8
Signed by: riq0h
GPG key ID: 010F09DEA298C717

View file

@ -38,7 +38,7 @@ bash
以上のように処理の一つ一つには必ずしも大きな落ち度はなかったのに、想定外にもたらされた制限がドミ倒しのごとく連鎖してバックアップを全部失ってしまった。なお、ずいぶんすっとぼけた前振りを延々としてきたが、インシデント発覚時点で僕のMastodonインスタンスは全然普通に動いていたので現実の障害には至っていない。 以上のように処理の一つ一つには必ずしも大きな落ち度はなかったのに、想定外にもたらされた制限がドミ倒しのごとく連鎖してバックアップを全部失ってしまった。なお、ずいぶんすっとぼけた前振りを延々としてきたが、インシデント発覚時点で僕のMastodonインスタンスは全然普通に動いていたので現実の障害には至っていない。
さしあたり、容量制限によって機能を果たせない`wrangler`に代わり`rclone`を採用してスクリプトの内容を刷新した。さらに、ローカル側にも古いファイルを一定期間置く形に改めた。こうすればローカルとオブジェクトストレージの両方に一応バックアップが残るだろう。 さしあたり、容量制限によって機能を果たせない`wrangler`に代わり`rclone`を採用してスクリプトの内容を刷新した。加えて、ローカル側にも古いファイルを一定期間置く形に改めた。こうすればローカルとオブジェクトストレージの両方に一応バックアップが残るだろう。
```bash ```bash
#!/bin/bash #!/bin/bash
@ -55,7 +55,50 @@ rclone sync copy /home/ユーザ/backup/ r2:mastodon-backup
echo "Mastodone." echo "Mastodone."
``` ```
初稿公開後、FediverseのFFからエラー制御ぐらいは組み込んだ方がよいのではとの指摘を受け、実際にスクリプトも頂戴したのでありがたく活用させて頂くことにした。以下に実例を示す。
```
#!/bin/env bash
set -euo pipefail
# Configurable variables
INSTANCE_DIR="$HOME/インスタンスのディレクトリ"
BACKUP_DIR="$HOME/backup"
BACKUP_LIFETIME_DAYS=7
DATE_FORMAT="%Y%m%d_%H-%M-%S"
DB_CONTAINER="mastodon-db-1"
DB_USER="mastodon_user"
DB_NAME="mastodon_db"
RCLONE_DESTINATION="r2:mastodon-backup"
# Error handling
trap 'echo "😢 An error occurred. Exiting." && exit 1' ERR
# Start backup
echo "🚀 Backup ready..."
cd "$INSTANCE_DIR"
# Database backup
BACKUP_FILE="$BACKUP_DIR/$(date +$DATE_FORMAT).gz"
docker exec $DB_CONTAINER pg_dump -Fc -U $DB_USER $DB_NAME | gzip -c >"$BACKUP_FILE"
echo "✅ Success!"
# Sync backup
echo "🔄 Syncing..."
find "$BACKUP_DIR" -mtime +$BACKUP_LIFETIME_DAYS -name "*.gz" -exec rm -f {} \;
rclone copy "$BACKUP_DIR" $RCLONE_DESTINATION
echo "👍 Mastodone."
```
僕の例はとりあえず目的に適う最小限のものだったが、このスクリプトは予め変数を代入させることで編集性を高めている。さらに、`set -euo pipefail`コマンドで安全性にも配慮している。`-o`はシェルオプションの有効化、`-e`はコマンドがエラーを起こした際の強制終了、`-u`は変数の未入力をエラーとして扱う効果をそれぞれ持つ。
最後に`pipefail`がパイプラインの左側のエラーを検知してくれる。一見、`-e`オプションがあれば`pipefail`は不要と思われるが、実はパイプラインに限っては右側のエラーしか認識しないため確実な制御には一連の手続きが必須である。これらのオプションによりエラーが検出されると、`trap`コマンドがエラーシグナル終了コード1を拾って専用のメッセージが発動する仕組みだ。
いや、しかしさすがに丁寧すぎやしないか まるで教本のサンプルコードを彷彿させる。でもこういう感じのを5分くらいでさっと書けるようになったら楽しいだろうな。
## おまけ ## おまけ
そもそもCloudflare R2上のバックアップファイルを定期的に消していたのは一定以上のデータ格納量を上回ると課金されるためだが、今回の件とは無関係にMastodonインスタンスのメディアファイルをずっと預けっぱなしにしていたのでどのみち金を払う羽目になった。それにしてもおぞましい金額だ。メルカリで使い古しの参考書を売って100円ほど銭を稼がなければならない。 そもそもCloudflare R2上のバックアップファイルを定期的に消していたのは一定以上のデータ格納量を上回ると課金されるからだが、今回の件とは無関係にMastodonインスタンスのメディアファイルをずっと預けっぱなしにしていたのでどのみち金を払う羽目になった。それにしてもおぞましい金額だ。メルカリで使い古しの参考書を売って100円ほど銭を稼がなければならない。
<iframe src="https://mystech.ink/@riq0h/111388760298229673/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="1300" allowfullscreen="allowfullscreen"></iframe><script src="https://mystech.ink/embed.js" async="async"></script> <iframe src="https://mystech.ink/@riq0h/111388760298229673/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="1300" allowfullscreen="allowfullscreen"></iframe><script src="https://mystech.ink/embed.js" async="async"></script>