備份 Mastodon
我是 https://bikers.social 的管理員,這是一個給機車騎士的 Mastodon 站台 🏍️
Postgres 是站台備份中最重要的部分。如果遺失了資料庫,就真的完了。我的密鑰也都有備份。
我舊的 Mastodon 備份策略是定期執行 pg_dumps,並透過 scp 傳到另一台機器。這樣其實已經非常夠用了,因為那台機器也會備份到我本地的 NAS。不過,我得半定期地手動清理舊備份,而且現在站台已經運行一段時間了,有個更好的方案會很不錯。
我最近稍微改造了一下,改用 Cloudflare R2。
R2
我把站台的所有資源都放在 R2 上。它的儲存費用比 S3 便宜得多,而且沒有輸出費用!如果用 S3,我會有點擔心會收到意料之外的頻寬帳單。
截至 2023 年 5 月,R2 也支援 lifecycle policies(生命週期原則)。
設定
首先,建立一個新的 R2 bucket。這個 bucket 將用於儲存。請確保它沒有開放公開存取!
接著,我們要設定本地的 aws cli。我建立了一個僅限該 bucket 存取的 API token,具備物件讀取/寫入權限,並且只限定我的 Mastodon 伺服器的 IP 位址才能使用。執行 aws configure,然後貼上新的帳號 ID 和 secret。
AWS cli 預設會假設你要使用的端點是 Amazon。較新版本的 CLI 可以在 config 中進行設定,但你的套件庫很可能已經過時。對於後續的所有指令,我設定了
alias aws='aws --endpoint-url https://<account ID>.r2.cloudflarestorage.com'
接著我們就可以設定 lifecycle policy 了。
前往你的 bucket 設定,然後找到 lifecycle policy

我設定了一條 lifecycle rule(生命週期規則),讓每日備份保留一週,每週備份保留 6 週,每月備份保留 6 個月。
腳本
我的備份腳本非常簡單。執行時,它會為當天建立一個檔案,然後使用指定的 prefix 上傳至 R2。
#! /bin/bash
prefix=${1:-daily}
date=$(date '+%Y-%m-%d')
pg_dump -Fc -Z 0 -U mastodon mastodon_production | xz -T4 > $date.sql.xz
aws --endpoint-url https://<account ID>.r2.cloudflarestorage.com s3 cp ./$date.sql.xz s3://<bucket name>/$prefix/$date.sql.xz如果沒有指定 prefix,則預設為每日備份。
我選擇用 xz 來備份。它能提供數一數二的壓縮率,代價是速度非常慢。我的 Mastodon 站台在規格上有點過剩,因為用的是 Hetzner 的主機,而且站台流量並不算高。
pg_dump -Fc -Z 0 - 使用自訂格式,但停用壓縮,因為我們會用 xz 來壓縮
xz -T4 會使用 xz 壓縮,且最多使用 4 個執行緒。我試過 -T0,結果直接把全部 16 個執行緒都跑滿了,有點太超過。只用 4 個還是能以夠快的速度完成。
Crontab
手動測試時,我執行了
./backup.sh daily
./backup.sh weekly
./backup.sh monthly並確認所有檔案都已正確建立後,我設定了我的 crontab
0 12 * * * /home/mastodon/backup.sh daily
0 13 * * 0 /home/mastodon/backup.sh weekly
0 14 1 * * /home/mastodon/backup.sh monthly這樣會有一些重複的工作,但在這裡不是什麼大問題。我把它們排程在我清醒的時段執行,因為我還設定了在備份完成時透過 Telegram 通知我。
改進
未來我可能會改用 wal-g。我覺得以目前的情況來說這樣有點殺雞用牛刀,而且用 pg_dump 的備份/還原流程非常簡單。如果資料庫的大小變得太大,或是需要 point-in-time recovery(時間點還原) 功能,我會再重新考慮。
隨機一篇部落格