在 VPS 上部署 Vaultwarden 密码库
用 Docker 部署 Vaultwarden,创建账号后关闭注册。配置 HTTPS,并在独立环境恢复数据、附件和客户端同步。
在 VPS 上部署 Vaultwarden,可以让 Bitwarden 客户端使用自己的服务器。开始前先准备 HTTPS 域名、独立备份和账号恢复资料;密码库装好后还需要持续维护。
容器先只发布到回环地址
在独立目录创建 compose.yaml,把域名换成实际地址。以下沿用官方镜像,首次创建账号暂时允许注册:
services:
vaultwarden:
image: vaultwarden/server:1.37.4@sha256:efb3cde962015fcc036b2ea625242248611943b27212ebf4392841fb30fad055
restart: unless-stopped
environment:
DOMAIN: https://vault.example.com
SIGNUPS_ALLOWED: "true"
ports:
- "127.0.0.1:11001:80"
volumes:
- ./vw-data:/data
启动前检查端口与目录。这里固定 1.37.4 及其多平台索引摘要,恢复时使用相同版本;索引会按机器架构选择镜像。本文的隔离验证使用 Linux ARM64,不能据此声称 AMD64、版本升级或真实客户端已经验收。以后更新先读发行说明,保留旧镜像、配置和可恢复副本,不直接将标签换成 latest。
docker compose config --quiet
docker compose up -d
docker compose logs --tail=100
创建自己的账号后,关闭公开注册
首次入口限制为自己可以访问的方式,创建账号后立即将 SIGNUPS_ALLOWED 改成 "false",执行 docker compose up -d 重建。确认新注册被关闭,再开放日常需要的域名入口,避免初始化期间让陌生人先注册。
宿主机 Caddy 的上游使用 127.0.0.1:11001。网页密码库需要安全上下文,日常使用最终 HTTPS 地址;DOMAIN 与实际访问地址一致。本例不启用管理后台,不添加网上随手复制的 ADMIN_TOKEN。
同步需要实际读写一次
Bitwarden 客户端选择自托管服务器,填写自己的 HTTPS 地址。建立一条虚构记录,验证手机能同步;在手机修改备注,再到网页检查。客户端可以解锁本地缓存,不代表刚刚修改的内容已经上传到服务器。
保存主密码和恢复方式,服务器备份无法代替账号恢复资料。访问与备份权限都按密码库数据的重要性安排。
完整备份包含数据库与附件
本例使用 SQLite,/data 对应宿主机的 vw-data。数据库保存账号、记录和附件元数据,附件本体在 attachments 目录;只保存一个数据库文件,不能恢复附件。rsa_key* 用于签发登录令牌;启用过管理后台时还可能有含敏感配置的 config.json。保留整个目录、Compose 和部署环境文件,并将副本加密后存到独立位置,避免把密钥、密码或管理员令牌放进公开仓库。MySQL、PostgreSQL 的数据库还要另做一致性备份,下面命令不适用于它们。
1.37.4 自带 /vaultwarden backup,会通过 SQLite 的 VACUUM INTO 生成 /data/db_时间.sqlite3。它只生成数据库快照,不会替你打包附件。下面先生成快照,再停止这一个服务,复制完整目录;操作前先限制入口,暂停所有客户端修改和附件上传,确认没有其他写入任务。快照与附件须来自同一个停止写入的窗口,不能拿较早的快照配上后来继续变化的附件目录。请在该 Compose 所在目录执行,将受保护备份目录改成实际路径,按每次输出记录新快照的准确文件名:
set -euo pipefail
umask 077
backup_dir='/srv/protected-backups/vaultwarden'
install -d -m 700 "$backup_dir"
stamp=$(date -u +%Y%m%dT%H%M%SZ)
docker compose exec -T vaultwarden /vaultwarden backup
docker compose stop vaultwarden
tar --numeric-owner -cpf "$backup_dir/vw-data-$stamp.tar" -C . vw-data
test -s "$backup_dir/vw-data-$stamp.tar"
(cd "$backup_dir" && sha256sum "vw-data-$stamp.tar" > "vw-data-$stamp.tar.sha256")
cp -- compose.yaml "$backup_dir/compose-$stamp.yaml"
# 如果使用 .env,也单独保存受保护副本;不要输出其内容。
if [ -f .env ]; then cp -- .env "$backup_dir/env-$stamp.private"; fi
docker compose up -d vaultwarden
这是 Linux 主机上的命令。任何一步失败都先停下来查看,确认副本完整后再恢复服务;不要为赶进度删掉原目录。哈希用于检查传输是否改变字节,不能替代恢复验证,也不提供备份加密。
在另一台受控机器或全新目录中恢复,不要覆盖仍在服务的 vw-data。安全复制备份、校验文件和原配置,先验哈希,再用空目录解包。下面以备份内自带的数据库快照为准:把 snapshot 改成备份操作实际输出的文件名,不能凭示例猜测。如果选用这种独立快照,旧 db.sqlite3-wal 不能配上它;直接复制原数据库与其 WAL 则必须成对恢复,两种方式不要混用。
set -euo pipefail
umask 077
backup_file='/实际受保护路径/vw-data-实际时间.tar'
restore_dir='/srv/vaultwarden-restore-check'
test -r "$backup_file" && test -s "$backup_file"
(cd "$(dirname "$backup_file")" && sha256sum -c "$(basename "$backup_file").sha256")
# 必须是尚不存在的独立目录;存在时停止,另选目录,不清空旧数据。
test ! -e "$restore_dir"
install -d -m 700 "$restore_dir"
tar --numeric-owner -xpf "$backup_file" -C "$restore_dir"
cd "$restore_dir"
snapshot='db_实际UTC日期_实际时间.sqlite3'
test -r "vw-data/$snapshot" && test -s "vw-data/$snapshot"
cp -- "vw-data/$snapshot" vw-data/db.sqlite3
rm -f -- vw-data/db.sqlite3-wal vw-data/db.sqlite3-shm
归档必须来自自己刚核验的可信副本,不能把陌生 tar 包以管理员权限解开。保留目录的原所有者和权限;换机器时根据实际容器运行用户核对读写权限,不要用 chmod -R 777 解决问题。
恢复出来的 vw-data 若含 config.json,先核对其中保存的域名、注册和邮件设置。它的可编辑配置会覆盖环境变量,启动日志会提示哪些项被覆盖;仅把 Compose 中的 DOMAIN 或 SIGNUPS_ALLOWED 改掉,不一定改变实际值。保留原配置副本,在恢复实例中按原管理方式调整需要更换的设置,再检查新注册确实被关闭。不要删除 config.json 来绕过这项检查。
另建 compose.restore.yaml,使用同一固定镜像、独立项目名、不同端口与测试域名,注册保持关闭;不要让恢复副本借原域名接收日常客户端写入:
services:
vaultwarden:
image: vaultwarden/server:1.37.4@sha256:efb3cde962015fcc036b2ea625242248611943b27212ebf4392841fb30fad055
restart: unless-stopped
environment:
DOMAIN: https://vault-restore.example.com
SIGNUPS_ALLOWED: "false"
ports:
- "127.0.0.1:11002:80"
volumes:
- ./vw-data:/data
docker compose -p vaultwarden-restore-check -f compose.restore.yaml config --quiet
docker compose -p vaultwarden-restore-check -f compose.restore.yaml up -d
测试域名需要你自己配置受控入口和有效 HTTPS。恢复副本先检查启动日志、普通账号登录、原记录、附件下载、注册关闭,以及一条新的虚构记录能否写入并由另一登录会话读回。真实手机、浏览器客户端还要按上一节独立验证;确认迁移成功前保留原目录和备份,切换时只保留一个日常写入端。
本次恢复演练使用固定 1.37.4 的 Linux ARM64 镜像和独立内网:一个合成普通账号、一条合成记录与 257 字节附件。原生快照通过 SQLite 完整性检查,恢复前逐文件比对完整目录的内容、所有者和权限;仅按上述规则替换数据库并移除旧 WAL/SHM。恢复后普通账号能重新登录,原记录与附件字节保持,关闭注册生效,新的登录会话也能读到恢复后的修改。附件下载链接的短期令牌会重新签发,不要求链接字符串完全不变。这验证的是服务端 API 的合成数据恢复,未验证真实 Bitwarden 客户端的密钥派生、解密、手机同步或公网 HTTPS,也不代表 AMD64、版本升级及双重认证已经测试。
选 VPS 时,把备份和维护一起考虑
已有机器资源够用,可以先用独立目录、端口与 HTTPS 部署;首次自建时按Docker 应用选购比较入口与资源。购买前同时安排更新、独立备份与恢复验证。只有装好容器,却没有可恢复数据和账号资料,出现故障时仍可能取不回密码库。
少量个人账户可以从 2 GB 内存的 Linux 实例试部署,为其他容器与更新留余量;有附件时按实际增长选盘。新手可查看 雨云 RCS 的系统与面板配置,自行管理测试环境可比较 Evoxt 的实例与备份范围。平台备份之外仍保存受保护的应用副本,确认客户端同步和恢复完成后再延长账期。




