目录

Vaultwarden 备份

前言

三年前开始 使用 Vaultwarden(非官方的 Bitwarden),但是始终没有对它进行完整的备份操作,偶尔记得就到处备份一下,心里总感觉有点虚,一方面容易泄漏数据,另一方面害怕那天不然硬件暴毙东西就全没了。今天闲下来就对 Vaultwarden 进行一下完整的备份。

思路

测试了一下将整个目录导出后,邮箱信息、2FA 等都完整保留,就没有像大多数人一样只备份 数据库attachments 目录,就直接压缩打包整个目录到指定目录下即可

由于群晖的 CloudSync 套件支持加密备份到各类云或 Webdav,备份到指定目录下也可以实现自动加密备份到云,实现数据脱离硬件备份,防止硬件暴毙丢失关键数据

docker compose

由于一开始使用群晖 docker 套件启动的容器,为了后续方便的进行恢复操作,根据 官方 WIKI 写了下 docker-compose.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
version: '3'

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    environment:
      WEBSOCKET_ENABLED: "true"  # Enable WebSocket notifications.
      ROCKET_PROFILE: release
      ROCKET_ ADDRESS: 0.0.0.0
      ROCKET_PORT: 80
      SMTP_HOST:
      SMTP_FROM:
      SMTP_PORT:
      SMTP_USERNAME:
      SMTP_PASSWORD:
      SMTP_SECURITY:
      SIGNUPS_ALLOWED: "false"
      INVITATIONS_ALLOWED: "false"
    volumes:
      - ./data:/data
    ports:
      - xxxx:3012
      - xxxx:80

备份脚本

现在写 Shell 就不需要一点一点搜索测试了,直接 chatgpt,说明需求后直接给出脚本代码,雀食爽

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/bin/bash

# 设置全局变量
SRC_DIR=/path/to/source/dir
DST_DIR=/path/to/destination/dir
MAX_NUM=30
LOG_FILE=${DST_DIR}/Error_Log_$(date +%Y%m%d_%H%M%S).log
ARCHIVE_FILE=${DST_DIR}/$(basename ${SRC_DIR})_$(date +%Y%m%d_%H%M%S).tar.gz
BARK_URL=https://api.day.app/{yourkey}/Bitwarden备份出错/

# 如果目标目录不存在则创建目标目录
if [ ! -d "${DST_DIR}" ]; then
    mkdir -p ${DST_DIR}
fi

# 打log函数
function log {
    echo "$(date +'%Y-%m-%d %H:%M:%S') $1" >> ${LOG_FILE}
    if [[ $1 == *"错误"* || $1 == *"出现"* ]]; then
        echo "$(date +'%Y-%m-%d %H:%M:%S') $1" >> ${DST_DIR}/ErrorLog_$(date +%Y%m%d_%H%M%S).log
        # bark发送通知
        curl "${BARK_URL}/${1}_$(date +%Y%m%d_%H%M%S)"
    fi
}

# 压缩函数
function compress {
    echo "开始压缩 ${SRC_DIR}"
    tar -czvf ${ARCHIVE_FILE} ${SRC_DIR} > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "压缩完成,文件存储在 ${ARCHIVE_FILE}"
    else
        log "压缩出现错误,请检查!"
    fi
}

# 删除旧压缩包函数
function delete_old_archives {
    num=$(ls -l ${DST_DIR} | grep "^-" | wc -l)
    while [ ${num} -gt ${MAX_NUM} ]
    do
        file=$(ls -rt ${DST_DIR}/*_*.tar.gz | head -n 1)
        if [ -n "${file}" ]; then
            rm -f "${file}"
            echo "删除旧文件 ${file}"
        else
            echo "没有找到旧文件"
            break
        fi
        let num--
    done
}

# 主函数
function main {
    compress
    delete_old_archives
}

# 执行主函数
main

执行

由于我是使用群晖,就直接使用计划任务,定时执行脚本即可,如果是直接在云服务器上运行的话,也可以使用 crontab 命令来执行

1
2
# 每天凌晨1点执行脚本
(crontab -l ; echo "0 1 * * * /bin/bash /path/to/your/script.sh >/dev/null 2>&1") | crontab -