備份與還原
在系統設定 → 備份設定。備份工作有自己的 Cron 排程,與任務排程無關。
備份內容
- Walis 資料庫,透過
VACUUM INTO——是一致的副本,不是對執行中資料庫做檔案複製。 - 建置產出檔案。
- 你列出的額外絕對路徑,一行一個。目錄整個打包,符號連結會跳過。
- 選用的 PostgreSQL,透過
pg_dump。
加密
Walis 自己的版本化格式:金鑰由通關密語經 PBKDF2-SHA256 導出,壓縮檔切成一塊塊各自驗證的 AES-256-GCM 區塊,結尾另有一個驗證過的結束標記。被改過或被截斷的備份會在還原任何內容之前就被拒絕。還原要透過 Walis——備份頁面或 POST /api/backup/restore,還原端點只接受這種格式。舊版用 OpenSSL Salted__ CBC 容器寫出的備份仍然讀得進來,供搬遷用,但不會再寫出那種格式。
只要啟用備份或設了任何目的地,通關密語就是必填(16 到 1,024 個字元),沒填的話畫面不讓你存。備份內含密碼雜湊與已儲存的憑證,不能以明文離開這台機器。
目的地
按新增目的地會開一個精靈:選擇類型 → 建立應用程式(或存取金鑰)→ 授權 → 位置與名稱 → 測試並完成。
| 類型 | 需要什麼 |
|---|---|
| 本機或外接磁碟 | 這台機器上的一個目錄。掛載起來的 NAS 或外接磁碟也算。 |
| S3 相容(R2、AWS S3、MinIO) | 一組存取金鑰,不必註冊應用程式。 |
| Dropbox | 在 Dropbox 建立應用程式並授權一次。單一檔案上限 150 MB。 |
| Google Drive | 在 Google Cloud 建立 OAuth 用戶端並授權一次。 |
| OneDrive | 在 Azure 註冊應用程式並授權一次。單一檔案上限 250 MB。 |
全部都在程序內實作——SigV4 由 Walis 自己簽。沒有任何一種會去呼叫 aws、rclone 之類的外部程式,所以不必額外裝東西,也不必跟著它們更新。
三家 OAuth 的權杖是怎麼拿到的
Dropbox、Google Drive 與 OneDrive 的做法一樣,麻煩的地方也一樣:它們要的是 refresh token,而那不是能從設定頁複製出來的東西。
精靈幫你把兌換這一段做掉:
- 你在對方的主控台建立一個應用程式,把 client ID 與 client secret 填進精靈。
- Walis 用正確的參數組出授權網址給你。開這個網址、同意授權的是你,Walis 不會自己去抓它。
- 你把授權碼貼回來。Google 與 OneDrive 授權後會跳到
http://localhost而顯示「無法連線」——這是正常的,把整段網址列複製下來,精靈會自己把授權碼撈出來。Dropbox 則直接把授權碼顯示在頁面上。 - Walis 在伺服器端用授權碼換 refresh token 並存起來。
所以你的 client secret 不會出現在命令列上,而授權碼——只能用一次、幾分鐘就失效——也不會進到日誌裡。如果你已經從別的地方拿到 refresh token,有一個直接貼上的選項。
編輯既有目的地時,機密欄位顯示成 ********。原樣留著就代表沿用,改個資料夾不必把憑證重打一遍。
Dropbox
- 到 Dropbox App Console 按 Create app。
- API 選 Scoped access,存取範圍選 App folder(備份只會放在自己的資料夾)或 Full Dropbox,取一個名字。
- 權限要在授權之前設好——Permissions 分頁勾
files.content.write、files.content.read與files.metadata.read。先授權再改權限的話,拿到的 token 沒有那些權限,得整個重來。 - 回 Settings 分頁複製 App key 與 App secret。
授權網址會帶 token_access_type=offline。少了它,Dropbox 只會給一個短命的 access token、根本不給 refresh token——自己湊網址失敗多半是這個原因。
Google Drive
- 到 Google Cloud Console 的 API 和服務 → 憑證,選一個專案(沒有就建一個)。
- 啟用 Google Drive API。
- 設定 OAuth 同意畫面:使用者類型選外部,填名稱與信箱,並把你自己的 Google 帳號加進測試使用者。
- 建立憑證 → OAuth 用戶端 ID,應用程式類型選電腦版應用程式,複製用戶端 ID 與用戶端密碼。
有兩件事最好在依賴它之前就知道:
- 同意畫面停在「測試中」時,refresh token 七天就會失效。 備份跑了一週後突然開始失敗,幾乎都是這個。到同意畫面按「發布應用程式」改成正式狀態,就不會有七天的限制。
- 正式狀態不等於永久。refresh token 閒置約六個月仍會被撤銷——每天跑的備份不會遇到,但一個停用很久的目的地重新啟用時就會遇到。它的失敗看起來跟七天那個一模一樣,所以要先確認自己碰到的是哪一種。
授權網址會帶 access_type=offline 與 prompt=consent。少了 prompt=consent,第二次授權不會再給 refresh token,因為 Google 只在第一次同意時發。如果兌換回來沒有 refresh token,是因為這個應用程式之前授權過。到 Google 帳戶的「第三方存取」把它移除,再用精靈產生的網址重新授權一次。
OneDrive
- 到 Azure 入口網站的應用程式註冊 → 新增註冊。
- 支援的帳戶類型選「任何組織目錄中的帳戶和個人 Microsoft 帳戶」;重新導向 URI 選 Web,填
http://localhost。 - 在「概觀」複製應用程式(用戶端)識別碼。
- 到憑證及祕密新增用戶端密碼,馬上複製它的值——離開頁面就再也看不到了。
- API 權限要有 Microsoft Graph 的委派權限 Files.ReadWrite 與 offline_access。
用戶端密碼有到期日。 到期那天備份就會開始失敗。把它記進行事曆:到期前建一把新的並回來重新授權。
S3 相容
不必註冊應用程式,只要一組金鑰。精靈會先問是哪一家,因為這三種差在容易搞錯的地方。
| 區域 | Endpoint | |
|---|---|---|
| Cloudflare R2 | auto | https://<帳號 ID>.r2.cloudflarestorage.com |
| AWS S3 | bucket 的區域,例如 ap-northeast-1 | 留空,Walis 會自己組 |
| MinIO/其他 | 依服務要求,通常是 us-east-1 | 服務自己的網址 |
R2 到 管理 R2 API 權杖建立權杖,權限選物件讀取與寫入並限定那個 bucket。AWS 則建一個 IAM 使用者,只給那個 bucket 的 s3:PutObject、s3:GetObject、s3:DeleteObject 與 s3:ListBucket 就夠了——一個上傳備份的身分沒有理由拿更大的權限。
備份會放到哪裡
路徑欄位在每種類型的意思不一樣,這是另一個常見的坑:
| 類型 | 路徑欄位 |
|---|---|
| 本機 | 目錄的絕對路徑。 |
| S3 | bucket 底下的前綴,可以留空。 |
| Dropbox、OneDrive | 相對於帳號根目錄的資料夾路徑(Dropbox 的 App folder 模式則相對於應用程式資料夾)。不存在會自動建立。 |
| Google Drive | 資料夾 ID,不是名稱也不是路徑。在 Drive 開啟那個資料夾,網址 folders/ 後面那一段就是。 |
完成
最後一步會自動測一次連線,旁邊有再測一次。測試失敗也可以先完成,之後再回來改。
按「完成」只是把目的地放進設定表單。 要回到備份頁按儲存設定才會生效——跟這一頁其他改動一樣。
保留天數是逐目的地套用,規則相同。金鑰與通關密語讀回來都是 ********;原樣送回代表沿用。
還原
還原會清空目前所有資料再寫回備份內容,無法復原。
- 備份與資料庫種類無關,所以在 SQLite 上取的備份可以還原到 PostgreSQL、MySQL 或 SQL Server。 這也是從單節點搬到多節點的正規路徑。
- 資料庫裡的機密在備份包內維持密文(
enc:v2:),不含加密主金鑰;跨機器還原時要把原資料目錄的secret.key複製過去,或設定相同的Security__EncryptionKey。金鑰檔不會被放進備份,額外備份路徑涵蓋資料目錄時也一樣。 - 稽核紀錄在還原時會與既有紀錄合併保留,不會被清空。
- 產出檔案是否一併還原可選。
- 還原期間會鎖定叢集並拒絕在有建置執行中時進行,避免執行中的建置在還原後寫回結果。
驗證
沒還原過的備份只是一個假設。通關密語是單一失效點——弄丟就救不回來,這是設計如此。把它存在不是被備份那台機器的地方。