我朋友有个习惯:所有网站的密码都让 Chrome 记住。
上次他电脑重装系统,浏览器没登录账号,收藏夹、密码全丢了。找了半天,最后靠手机上一个一个试,折腾了一晚上。
我问他为什么不买个密码管理器,他说 1Password 一年三百多,有点贵。
那就自己搭一个。Vaultwarden,Bitwarden 的轻量实现,一个容器,几十兆内存,功能该有的都有。
这篇是完整部署记录。
Vaultwarden 是什么
Bitwarden 官方服务端是 Java 写的,跑起来要好几 G 内存。
Vaultwarden 是社区用 Rust 重写的实现,兼容 Bitwarden 的官方客户端,一个容器 100M 左右内存就能跑。
- 手机 App 能用官方 Bitwarden
- 浏览器插件能用官方 Bitwarden
- 桌面上有客户端
- 支持 TOTP 两步验证、附件、分享、组织
我自己用了小半年,密码、密钥、银行卡信息全在里面。
一、先解决 HTTPS 问题
这一步不能跳。
Bitwarden 的所有客户端都强制要求 HTTPS,用 http 连不上(浏览器插件直接报错,手机 App 也不行)。
所以顺序是:
- 先准备好域名解析(比如
vault.你的域名.com指到服务器) - 先搭好 Nginx Proxy Manager 或者手写 nginx 配证书
- 再启动 Vaultwarden
我这边是用 Nginx Proxy Manager 套的证书,后面有一篇专门写它。
二、compose 配置
services:
vaultwarden:
container_name: vaultwarden
image: vaultwarden/server:latest
restart: unless-stopped
environment:
- DOMAIN=https://vault.你的域名.com
- SIGNUPS_ALLOWED=false
- INVITATION_ALLOWED=true
- ADMIN_TOKEN=换成你自己的长随机串
- TZ=Asia/Shanghai
volumes:
- /opt/docker/vaultwarden/data:/data
ports:
- "127.0.0.1:8222:80"
mem_limit: 256m
几个参数解释一下:
| 参数 | 作用 |
|---|---|
DOMAIN | 你的访问地址,客户端用它拼 WebSocket 和邀请链接,必须填 https |
SIGNUPS_ALLOWED | 是否开放注册。装完先设 true 注册自己,再改 false |
INVITATION_ALLOWED | 允许管理员发邀请 |
ADMIN_TOKEN | 管理面板的口令,必须设,不设就没法进 /admin |
注意端口映射写成 127.0.0.1:8222:80,只监听本机,外网通过反代进来。直接暴露 8222 到公网,等于把密码库挂在公网上。
三、启动并注册
cd /opt/docker/vaultwarden
docker compose up -d
docker compose logs -f
看到 Rocket has launched from 就起来了。
先把 SIGNUPS_ALLOWED 设成 true,重启容器,然后访问 https://vault.你的域名.com 注册第一个账号。
注册完立刻改回 false:
docker compose down
# 编辑 compose,SIGNUPS_ALLOWED 改成 false
docker compose up -d
四、客户端配置
浏览器插件:Chrome 商店搜 Bitwarden,装完点设置,服务器地址填 https://vault.你的域名.com,然后用刚才注册的账号登录。
手机 App:应用商店搜 Bitwarden,登录前先点设置里的"自托管环境",填同样的地址。
桌面客户端:官网下载 Windows/Mac 版,同样改服务器地址。
登录后会自动同步,新增的密码在各端都能看到。
五、管理面板
访问 https://vault.你的域名.com/admin,输入 ADMIN_TOKEN 进去。
能做这些事:
- 看用户列表,禁用/删除账号
- 发邀请链接给朋友(配合
INVITATION_ALLOWED=true) - 看诊断信息,检查 SMTP、数据库状态
- 备份数据库
我给朋友开了个账号,他自己维护自己的密码,我看不到他的内容——Vaultwarden 里每个用户的密码库是加密隔离的,服务端只有密文。
六、备份:这一步千万别省
密码库丢了,比丢手机还麻烦。
Vaultwarden 的数据全在 /opt/docker/vaultwarden/data 里,核心是 db.sqlite3。
备份方式:
# 停容器保证一致性
docker compose stop vaultwarden
# 打包整个 data 目录
tar czf /backup/vaultwarden-$(date +%Y%m%d).tar.gz \
-C /opt/docker/vaultwarden data
docker compose start vaultwarden
或者用 sqlite 的在线备份(不停容器):
docker exec vaultwarden sqlite3 /data/db.sqlite3 \
".backup /data/backup-$(date +%Y%m%d).sqlite3"
备份文件要放在另一台机器或者网盘上,别和原数据放同一块盘。
我设了个每周日凌晨的定时备份,用 rclone 同步到另一台机器。
七、踩过的坑
坑一:不设 ADMIN_TOKEN
第一次装完,/admin 打不开,报 404。查了才知道没设 ADMIN_TOKEN,管理面板根本没启用。
坑二:反代没配 WebSocket
密码库有个实时同步功能,靠 WebSocket。Nginx 反代时要把 Upgrade 头透传,不然多端同步会有延迟,得手动刷新。
Nginx Proxy Manager 里勾上 "Websockets Support" 就行,手写 nginx 要加:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
坑三:附件目录权限
Vaultwarden 上传附件(比如证件照片)存在 data/attachments,容器里的用户是 UID 1000。如果宿主机目录属主不对,上传会失败,日志里报 Permission denied。
sudo chown -R 1000:1000 /opt/docker/vaultwarden/data
坑四:忘记主密码就完了
Vaultwarden 服务端存的是加密后的数据,主密码忘了,谁也没法帮你解。只能从备份恢复,或者用恢复码。
所以注册时生成的 Emergency Kit(应急恢复码)一定要打印出来或者存到别的地方。
八、这套东西的价值
对比一下:
| 方案 | 一年成本 | 数据在哪 |
|---|---|---|
| 1Password | 约 300 元 | 别人服务器 |
| Bitwarden 官方 | 免费版够用,高级版 10 美元 | 别人服务器 |
| 自建 Vaultwarden | 电费几十块 | 自己机器 |
自建的代价是要自己维护、自己备份、自己保证 HTTPS。
但对有点技术基础的人来说,这套是值得的——密码这东西,存在自己机器上心里踏实。
最后
Vaultwarden 是我 Docker 全家桶里最没存在感的一个服务:装完就忘了,256M 内存,几年不用管。
但它是最重要的一项。照片丢了是遗憾,密码丢了是灾难。
下一篇写 Nginx Proxy Manager,把这一堆服务统一收进 https。
---
如果你也在折腾这套服务,碰到卡住的地方,可以加我微信 lige0552 聊聊。白天要上班,消息回得慢,看到都会回。