在所有自建自托管的开源服务中,Vaultwarden(Bitwarden 的轻量级 Rust 兼容服务端) 是最具价值、但也最让人“夜不能寐”的服务。
“用了两三年,里面存着银行密码、邮箱密钥、二次验证码 (TOTP)、加密货币助记词、数百个海内外网站的登录凭证。”
很多小伙伴兴高采烈地用一段 Docker 命令在软路由或者便宜 VPS 上跑起来后,就再也没有管过它。
直到某一天,服务器遭遇硬盘暴毙、机房母机故障失火、或者 VPS 商家因为被攻击直接把你封号清退——那一瞬间,你整个人生的数字资产将全部灰飞烟灭,连哭都找不到地方!
普通数据丢了可以重新下载,密码库一旦彻底丢失,就是毁灭性的数字灾难!
本文严格按照工业级数据灾备的 3-2-1 原则 与 EEAT 深度权威标准,手把手教你避开 SQLite 在线备份损坏的巨坑,构建一套全自动化异地热备与灾难自救系统!
一、一句话搞懂:为什么直接拷贝 db.sqlite3 会导致数据库损坏?
很多小白卖家或新手自建党,最常干的一件“假备份”蠢事就是:
在系统运行中,直接写个脚本:cp /data/db.sqlite3 /backup/这是极其致命的错误!
- 底层原因:现代 Vaultwarden 默认开启了 SQLite 的 WAL (Write-Ahead Logging,预写日志) 模式。
- 在用户频繁增删密码时,最新的数据并不在
db.sqlite3里面,而是在内存和旁边的db.sqlite3-wal临时日志文件里! - 如果你直接复制文件,极易截断正在写入的事务日志,导致备份出来的数据库彻底损坏、无法读取!
真正的安全备份,必须调用 SQLite 官方提供的热备份 API(通过命令 sqlite3 db.sqlite3 ".backup backup.sqlite3")或者使用成熟的自动化备份镜像。
二、数据灾备最高准则:3-2-1 架构设计
为了确保即使核弹炸了你的服务器,密码库也能毫发无伤,我们设计如下架构:
┌──────────────────────────────────────────────┐
│ 主力生产服务器 (本地 NAS / 软路由 / VPS) │
│ 运行 Vaultwarden 核心服务 │
└──────────────────────┬───────────────────────┘
│
(每 6 小时自动执行热备份并 GPG 加密)
│
┌─────────────────────────┴─────────────────────────┐
│ │
┌────────▼────────┐ ┌────────▼────────┐
│ 异地备份仓 A │ │ 异地备份仓 B │
│ Cloudflare R2 │ │ Google Drive / │
│ (免费 S3 对象存) │ │ 本地冷备 U 盘 │
└─────────────────┘ └─────────────────┘
- 3 份完整数据:1 份生产数据 + 2 份异地独立备份。
- 2 种存储介质:本地 SSD 硬盘 + 云端对象存储。
- 1 份异地冷备:即使你的物理机器被烧毁,云端备份随时能用任何电脑 3 分钟拉起!
三、实战:Docker 一键挂载自动化异地加密备份
我们使用开源界最稳定经过考验的 ttionya/vaultwarden-backup 容器,它自带对 SQLite WAL 的完美热备支持,并支持自动加密上传至 S3 / Cloudflare R2:
完整的 docker-compose.yml 生产级加固配置
version: '3.8'
services:
# 1. 核心密码库服务
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
environment:
- SIGNUPS_ALLOWED=false # 禁止未授权人员随意注册
- INVITATIONS_ALLOWED=false
- SHOW_PASSWORD_HINT=false
volumes:
- /opt/vaultwarden/data:/data
ports:
- "127.0.0.1:8080:80" # 仅监听本地,配合 Nginx 反代开启 HTTPS
# 2. 自动化安全备份容器
vaultwarden-backup:
image: ttionya/vaultwarden-backup:latest
container_name: vaultwarden-backup
restart: always
environment:
- CRON=0 */6 * * * # 每 6 小时自动执行一次备份
- ZIP_ENABLE=TRUE
- ZIP_PASSWORD=YourStrongEncryptionPassword123! # 极其重要的备份压缩包解密密码
- BACKUP_KEEP_DAYS=30 # 本地保留 30 天滚动备份
# 云端 S3 / Cloudflare R2 配置
- RCLONE_REMOTE_NAME=R2
- RCLONE_DESTINATION=R2:my-vaultwarden-backup/
volumes:
- /opt/vaultwarden/data:/vaultwarden:ro # 只读挂载,防止备份脚本误删生产数据
- /opt/vaultwarden/backup:/backup
- /root/.config/rclone:/config/rclone:ro # 挂载 rclone 授权配置文件
depends_on:
- vaultwarden四、灾难恢复实操:服务器炸了之后,如何 5 分钟满血复活?
当你的主服务器彻底损坏,拿到一台新机器后的极速恢复流程:
- 从 Cloudflare R2 或备份邮箱下载最新的加密压缩包(形如
backup_2026-09-08_06-00-00.zip)。 - 输入你设定的
ZIP_PASSWORD解压该文件,你会得到一个完全纯净健康的db.sqlite3以及attachments文件夹。 - 将这两个文件拷贝进新服务器的
/opt/vaultwarden/data目录。 - 运行
docker-compose up -d。 - 打开浏览器输入账号密码——所有密码凭据、两步验证 TOTP 毫发无伤、全部完美恢复!
五、常见报错与避坑速查表
| 报错现象 / 风险提示 | 核心原因分析 | 权威解决办法 |
|---|---|---|
打开网页提示 Websocket connection failed |
Nginx 反代没有配置 WebSocket 升级头部,导致多端无法实时同步。 | 在 Nginx 配置文件中加入 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";。 |
| 手机客户端无法登录或同步 | Vaultwarden 强制要求必须在标准的 HTTPS (SSL) 环境下运行。 | 使用 Nginx Proxy Manager 或 Caddy 自动申请免费 Let’s Encrypt 证书。 |
备份容器报错 Rclone copy failed |
Cloudflare R2 的 API Token 权限不足或存储桶名称输错。 | 在 R2 控制台生成带有 Admin Read & Write 权限的全新 Token。 |
六、一句话总结
没有异地灾备的自建,等于自杀! 拒绝无脑复制 SQLite 文件,拥抱 WAL 热备 + GPG 加密 + Cloudflare R2 异地双备份,让你的核心数字资产固若金汤!