部署
自己更新自己
Walis 內建一個更新 Walis 的任務。麻煩的地方在於建置是服務的子程序, 所以在腳本裡重啟服務會在結果寫回資料庫之前把自己殺掉——那次建置會永遠停在執行中。
解法是把工作拆成兩半:
| Daemon | 負責 |
|---|---|
com.spex.walis | 服務本體 |
com.spex.walis-restarter | 盯著 var/restart.request,被 touch 後 8 秒重啟服務 |
所以更新任務只做四件事——拉程式碼、建置到新的 releases/<時間戳>、切換 current 符號連結、 touch 觸發檔——然後正常結束。restarter 不在服務的程序樹裡,重啟不會影響那次建置的結果。 建置失敗就不會切換符號連結,服務維持在舊版本。
反向代理與 tunnel
<主機名稱>.example.com
→ cloudflared(LaunchDaemon)
→ Caddy 127.0.0.1:8080(LaunchDaemon)
→ 服務 127.0.0.1:11120三層都是 LaunchDaemon,重開機後不必有人登入就會回來。刻意不用 brew services—— 那是使用者 LaunchAgent,要登入才會跑。
兩個會咬人的地方:
AllowedHosts:ASP.NET 的 host filtering 會擋掉經反向代理進來的請求,要放寬。- 沙箱路徑要先解析:
/tmp與/var/folders的符號連結在路徑中間, 用沒解析過的路徑寫sandbox-exec規則會完全不生效,而且不會報錯。
備份
Walis 可以備份自己的 SQLite(用 VACUUM INTO,執行中也安全)、產出檔案、你列出的額外路徑, 以及用 pg_dump 備份 PostgreSQL。壓縮檔用 AES-256-CBC 加密,格式與 OpenSSL 相容, 所以還原時完全不依賴 Walis 還活著:
bash
openssl enc -d -aes-256-cbc -pbkdf2 -iter 600000 -md sha256 \
-pass pass:'<通關密語>' -in backup.tar.gz.enc -out backup.tar.gz目的地:本機或掛載的路徑、S3 相容儲存(R2 或 AWS,在程序內自簽)、Dropbox、Google Drive 與 OneDrive。 只要設了遠端目的地就強制要有通關密語——備份裡有密碼雜湊與雲端金鑰。