自建 Vaultwarden 有一个绕不过的硬门槛——它必须跑在 HTTPS 上,否则官方 Bitwarden 客户端会直接拒绝连接。 除此之外的部署都极轻:Vaultwarden 是 Bitwarden 服务端的 Rust 实现,一个容器才几十兆、空闲内存不到 100MB,跑在 1 核 1G 的小 VPS 上绰绰有余。正确顺序是:先用 Docker 起服务、再上反代配 HTTPS、然后立刻关掉开放注册并设好管理员令牌、最后把 /data 卷(里面有 SQLite 库、附件和那对 RSA 密钥)纳入每天备份。整套流程我在一台 1G 内存的机器上跑了半小时。
上面这段就是全文的结论块,可以直接拿走。下面是部署、收口、备份和排错。

为什么必须 HTTPS,不能图省事用 IP?
结论:Bitwarden 官方客户端(桌面/移动/浏览器插件)在非 HTTPS 的地址上会拒绝登录,这是客户端的硬编码安全策略,不是配置问题。
| 访问方式 | 客户端能否登录 | 说明 |
|---|---|---|
http://IP:8080 |
不能 | 除 localhost 外一律拒绝 |
| 域名 + 自签证书 | 通常不能 | 证书不受信任,客户端报错 |
| 域名 + 有效 HTTPS | 可以 | 需要可信证书 |
所以「先用 IP 测试,回头再配域名」这条路走不通。要把 HTTPS 当成部署的第一步,而不是上线前才补的收尾工作。
配置步骤速览

第一步:起容器

$ mkdir -p /opt/vaultwarden/data && cd /opt/vaultwarden
$ docker run -d --name vaultwarden --restart=unless-stopped \
-p 127.0.0.1:8080:80 \
-v /opt/vaultwarden/data:/data \
-e DOMAIN="https://vault.example.com" \
-e SIGNUPS_ALLOWED="true" \
-e WEBSOCKET_ENABLED="true" \
vaultwarden/server:latest
两个参数必须写对:DOMAIN 要和你最终的公网地址一字不差(客户端会把网页保管库地址、附件下载地址都按它拼),端口绑 127.0.0.1(只让本机反代能连,别对公网直开)。WEBSOCKET_ENABLED=true 让多设备间的改动近乎实时同步。
第二步:反代 + HTTPS

server {
listen 443 ssl;
server_name vault.example.com;
client_max_body_size 0; # 附件可能很大,禁用上传限制
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /notifications/hub {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
certbot --nginx -d vault.example.com 一条命令签证书后重载即可。client_max_body_size 0 必须加,否则超过默认 1MB 的附件上传会返回 413,而客户端只会笼统报「同步失败」,极难定位。
第三步:注册账号,然后立刻关掉注册

浏览器打开 https://vault.example.com,用你自己的邮箱注册第一个账号——第一个注册的账号自动成为管理员。注册完马上做两件事:
# 1) 关掉开放注册,防止陌生人注册
$ docker run -d --name vaultwarden --restart=unless-stopped \
-p 127.0.0.1:8080:80 \
-v /opt/vaultwarden/data:/data \
-e DOMAIN="https://vault.example.com" \
-e SIGNUPS_ALLOWED="false" \
-e WEBSOCKET_ENABLED="true" \
-e ADMIN_TOKEN="$argon2id$v=19$m=65540,t=3,p=4$你的argon2哈希" \
vaultwarden/server:latest
ADMIN_TOKEN 用于访问 /admin 管理页。别再填明文密码——新版 Vaultwarden 支持并推荐填 Argon2 哈希,用官方命令生成:
$ docker run --rm vaultwarden/server:latest /vaultwarden hash
# 交互输入你的管理密码,输出一段 $argon2id$... 的哈希,填进 ADMIN_TOKEN
第四步:备份,别只备份数据库

要备份的是整个 /data 目录,里面不止 db.sqlite3:还有附件目录、图标缓存,以及那对 RSA 密钥——密钥丢了,就算数据库完好,客户端也登不进、密码解不开。
# 方式 A:停机 + 打包整个卷(最稳)
$ docker stop vaultwarden
$ tar czf vault-data-$(date +%F).tgz -C /opt/vaultwarden data
$ docker start vaultwarden
# 方式 B:不停机,SQLite 在线安全备份
$ docker exec vaultwarden sqlite3 /data/db.sqlite3 ".backup '/data/backup-$(date +%F).sqlite3'"
方式 B 用的是 SQLite 的 .backup 命令——它能在数据库被写入的同时拿到一致快照,而直接 cp db.sqlite3 在写入时可能拷到半个事务、恢复后库是坏的。把这条并进你每晚的 rsync 增量备份 或 Compose 那套的卷备份流程里,才算真的守住。
已有密码库怎么迁过来?
结论:从官方 Bitwarden 或其它管理器迁移,走「加密导出 → 导入」两步,中途不让明文落地。
在旧库里导出(Bitwarden 桌面端:设置 → 导出保险库),选 .json 并勾选「加密导出」、设一个导出密码。得到加密文件后,在 Vaultwarden 网页端 →「工具 → 导入数据」,格式选 Bitwarden (json),上传并填入导出密码即可。
务必用加密导出,别用明文 CSV。 明文 CSV 一旦躺在下载目录、又被同步盘或网盘自动备份,等于把你的整个密码库摊在公网上——我见过有人导完明文 CSV 忘了删、同步到了共享盘,等于全公司的密码都暴露。
迁移完成后还有两件收尾:在 Vaultwarden 里重新配一遍两步验证(它支持 TOTP 双因素),以及在每一个客户端(桌面 / 手机 / 浏览器插件)把服务器地址改成 https://vault.example.com 并重新登录——服务端换了,客户端要一个个重指,没有「一键切换」这回事。
三个真会踩的坑
DOMAIN写错会让附件下载全挂。 客户端上传附件时用的下载地址是按DOMAIN拼的,写成http://、写成内网地址、或和实际域名不一致,都会导致「能登录但附件下不来」。改DOMAIN后必须重启容器。- 忘关注册 = 公开注册页。
SIGNUPS_ALLOWED=true期间,任何知道你域名的人都能注册账号、往你的库里塞数据。注册完第一个账号就立刻设false重建容器。要给家人开号,临时改回 true 加完再关。 - 1G 小内存上开了 WebSocket 又跑别的栈,可能 OOM。 Vaultwarden 本身很省,但如果同机还堆了数据库、网盘、探针,要留意总内存水位,必要时加 swap——机器上内存被吃光时,先崩的往往是数据库。
Vaultwarden 常见问题(2026)
Q:Vaultwarden 和官方 Bitwarden 客户端兼容吗?
A:兼容。它实现了 Bitwarden 的服务端 API,官方桌面端、移动端、浏览器插件都能连,只要在客户端的「自托管」设置里填你的 https://vault.example.com。数据格式也是兼容的,便于日后迁移。
Q:必须用域名,不能用 IP 吗?
A:必须用域名并配有效 HTTPS 证书。客户端对非 HTTPS 地址(除 localhost)会直接拒绝。没有域名的机器不适合自建密码库——这也是它的第一道门槛。
Q:注册功能关了,怎么再加用户?
A:把 SIGNUPS_ALLOWED 临时改回 true 重建容器,让新用户注册,注册完再改回 false。或者在 /admin 面板里邀请、由管理员控制。
Q:备份只复制 db.sqlite3 行不行?
A:不行。/data 里的 RSA 密钥和附件目录缺一不可,密钥丢了会导致已同步设备也无法解密登录。备份整个 /data,并且定期做一次恢复演练——没演练过的备份只是心理安慰。
Q:能在 Cloudflare 后面跑吗?
A:可以,也推荐。但要保证回源是 HTTPS 或让反代正确识别 X-Forwarded-Proto,且 DOMAIN 填的是公网 HTTPS 地址。若开了 Cloudflare 的缓存规则,务必对 Vaultwarden 子域 Bypass cache,别让 API 响应被缓存。
一句总结
自建密码库的难度不在技术,在几个「必须做对」的硬条件:域名 + HTTPS、注册收口、管理员令牌用哈希、备份覆盖整个 /data(尤其是密钥)。把这四件事做实,你就拥有一个数据完全在自己手里、服务商跑路也不影响的密码库——代价只是一个几十兆的容器。