目前我的Synology NAS上有跑docker,並且我想要將跑在docker上的Vaultwarden(自架密碼管理器)進行備份,不然哪天資料消失密碼也隨之消失,正好前陣子有註冊Oracle Cloud (Free Tier),免費的總容量(400GB)也夠我備份密碼庫這種小檔案,所以我就想說能不能讓Oracle當我的備援server,同時也備份部份資料,這樣也算是異地備份,所以就開始著手研究(問ChatGPT),其實簡單來說就是從Linux備份到另一台Linux,以下是操作過程:
前置作業
- 本地主機(我這邊是Synology NAS DSM 7.2.2,Linux)
- 遠端主機,Oracle VPS(Ubuntu Linux),或是你自己的server
- 遠端主機公網 IP
- 欲備份檔案
- 遠端主機私鑰
我這邊要備份的檔案路徑是:
/volume1/docker/vaultwarden
開始設定
到Synology NAS控制台 >> 任務排程表 >>新增

排程任務 >> 使用者定義指令碼

一般
- 任務名稱: 我這邊是vaultwarden backup
- 使用者帳號: 因為我這邊資料夾只有開權限給管理員群組,所以我這邊用NAS管理員帳號
排程
- 依照想要備份的頻率或特定哪一天做設定,我這邊是設定每天
任務設定
- 執行指令:
#!/bin/bash
DATE=$(date +%F) #取得當前日期作為檔名
TMP="/volume1/docker/vaultwarden_backup_${DATE}.tar.gz" #暫存的位置及檔名
REMOTE_USER="ubuntu" #遠端主機的使用者名稱
REMOTE_HOST="xxx.xxx.xxx.xxx" #更換成遠端主機的IP位置
REMOTE_PATH="/home/ubuntu/nas_backups/" #欲備份在遠端主機某個目錄下
SSH_KEY="/volume1/docker/ssh_key/id_rsa.key" #VPS的存取私鑰位置(建立VPS時下載的,先放到NAS上讓NAS可以讀取)
# 如果暫存位置在欲壓縮的檔案下要排除備份檔自己(目前不需要)
#tar czf "$TMP" -C "/volume1/docker" --exclude="vaultwarden_backup_*.tar.gz" vaultwarden
# 上傳備份檔(指定完整檔名)
scp -o StrictHostKeyChecking=no -i "$SSH_KEY" "$TMP" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}vaultwarden_backup_${DATE}.tar.gz"
# 刪除本地備份檔
rm "$TMP"
***建立排程任務後先不要執行***
要更改私鑰的權限
似乎在DSM介面即使設置私鑰擁有者和權限為管理員,進行ssh連線時仍會跳錯誤說權限太open,所以只好在NAS的系統後台執行(透過指令),有兩種方式可以解決:
- 透過ssh進入NAS操作(不熟Linux的人不太建議)
- 透過任務排程表建立一次性任務來執行
指令:
chmod 600 /volume1/docker/ssh_key/id_rsa.key
建立好後先執行任務
建議可以開日誌紀錄來查看指令是否執行正常:

到日誌儲存位置查看output log有沒有error
要先建立指紋
由於任務排程器沒有互動功能,而且第一次與遠端主機建立連線時會先確認指紋是否存在(確認此遠端主機是否可信任),所以我們必須先建立指紋,才不會出錯,同樣是要ssh進入NAS或透過任務排程表
總而言之第一次建立連現時會出現以下:
ssh -i /volume1/docker/ssh_key/id_rsa.key ubuntu@xxx.xxx.xxx.xxx
The authenticity of host 'xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)' can't be established.
ECDSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
這邊要輸入yes才能繼續連線
yes
如過透過ssh進入NAS就是以上的操作
如果要建立任務,指令如下:
ssh -i /volume1/docker/ssh_key/id_rsa.key ubuntu@xxx.xxx.xxx.xxx
yes
一樣執行後查看log有無出錯
手動試試執行一開始的備份任務
如果log沒輸出錯誤的話,那這時檔案應該已經正確傳送到遠端主機,我們來確認一下

果然有看到檔案
在遠端主機上啟動docker服務當作備援server
docker安裝的部分就跳過,網路上應該有很多教學,接下來要建立腳本來執行:
- 找到最新備份檔
- 刪除目前docker運行資料
- 解壓縮至目標目錄
- 重啟docker服務以套用新的備份資料
接下來我先在使用者根目錄建立sh資料夾,存放腳本,接著新增腳本
mkdir ~/sh
vi vaultwarden.sh
#!/bin/bash
BACKUP_DIR="/home/ubuntu/nas_backups" #剛才在NAS任務排程表打上的目標目錄
DATA_DIR="/home/ubuntu/docker" #存放docker的資料目錄
# 找最新備份檔
LATEST_BACKUP=$(ls -1t "$BACKUP_DIR"/*.tar.gz | head -n1)
if [ -z "$LATEST_BACKUP" ]; then
echo "找不到備份檔"
exit 1
fi
# 停止容器
docker stop vaultwarden
# 清空舊資料
rm -rf $DATA_DIR/*
echo "解壓備份檔:$LATEST_BACKUP"
tar -xzf "$LATEST_BACKUP" -C "$DATA_DIR"
# 啟動容器
docker start vaultwarden
把腳本檔設置成可執行
chmod +x~/sh/vaultwarden.sh
接著手動執行腳本試試
sh/vaultwarden.sh
沒有出錯的話應該就正常跑起來了,到這裡備份算是很成功,但是還需要在這裡進行定期執行腳本,我是設定每天從NAS備份,所以我的腳本就設定一天執行一次,設定crontab
crontab -e
選擇偏好的文本編輯器,然後在裡面加上
30 0 * * * /home/ubuntu/sh/vaultwarden.sh >> /home/ubuntu/sh/sh_log/vaultwarden.log 2>&1
欄位 | 意義 |
---|---|
0 | 分鐘 |
2 | 小時(凌晨2點) |
* | 每天 |
* | 每月 |
* | 每週的任何一天 |
/home/ubuntu/sh/vaultwarden.sh | 指定要執行的腳本 |
>> ... | 將輸出記錄到 log 檔案中 |
2>&1 | 把錯誤輸出(stderr)也重導向到標準輸出(stdout) 把 標準輸出(1) 和 標準錯誤(2) 都寫入 log |
然後別忘記建立log的資料夾sh_log
mkdir ~/sh/sh_log
簡單的備援伺服器就設定完成
不過如果要讓vaultwarden正常運作還必須要用ssl加密連線(https),之後會詳細說明如何設定(透過反向代理)